

<!DOCTYPE html>
<html lang="zh-CN" data-default-color-scheme=&#34;auto&#34;>



<head>
  <meta charset="UTF-8">
  <link rel="apple-touch-icon" sizes="76x76" href="/img/insert1.png">
  <link rel="icon" href="/img/insert1.png">
  <meta name="viewport"
        content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, shrink-to-fit=no">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  
  <meta name="theme-color" content="#2f4154">
  
    <meta name="description" content="无聊的人生只剩下无尽的空虚。">
  
  <meta name="author" content="Mike Taylor">
  <meta name="keywords" content="我的博客">
  
  <title>数据库笔记 - Mike Taylor</title>

  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" />


  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/github-markdown-css@4.0.0/github-markdown.min.css" />
  <link  rel="stylesheet" href="/lib/hint/hint.min.css" />

  
    
    
      
      <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js@10.4.0/styles/github-gist.min.css" />
    
  

  
    <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.css" />
  



<!-- 主题依赖的图标库，不要自行修改 -->

<link rel="stylesheet" href="//at.alicdn.com/t/font_1749284_ba1fz6golrf.css">



<link rel="stylesheet" href="//at.alicdn.com/t/font_1736178_kmeydafke9r.css">


<link  rel="stylesheet" href="/css/main.css" />

<!-- 自定义样式保持在最底部 -->


  <script id="fluid-configs">
    var Fluid = window.Fluid || {};
    var CONFIG = {"hostname":"gitee.com","root":"/","version":"1.8.8","typing":{"enable":true,"typeSpeed":30,"cursorChar":"|","loop":false},"anchorjs":{"enable":true,"element":"h1,h2,h3,h4,h5,h6","placement":"right","visible":"hover","icon":""},"progressbar":{"enable":true,"height_px":3,"color":"#29d","options":{"showSpinner":false,"trickleSpeed":100}},"copy_btn":true,"image_zoom":{"enable":true},"toc":{"enable":true,"headingSelector":"h1,h2,h3,h4,h5,h6","collapseDepth":0},"lazyload":{"enable":true,"onlypost":false},"web_analytics":{"enable":false,"baidu":null,"google":null,"gtag":null,"tencent":{"sid":null,"cid":null},"woyaola":null,"cnzz":null,"leancloud":{"app_id":null,"app_key":null,"server_url":null}}};
  </script>
  <script  src="/js/utils.js" ></script>
  <script  src="/js/color-schema.js" ></script>
</head>


<body>
  <header style="height: 70vh;">
    <nav id="navbar" class="navbar fixed-top  navbar-expand-lg navbar-dark scrolling-navbar">
  <div class="container">
    <a class="navbar-brand"
       href="/">&nbsp;<strong>Mike Taylor's</strong>&nbsp;</a>

    <button id="navbar-toggler-btn" class="navbar-toggler" type="button" data-toggle="collapse"
            data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <div class="animated-icon"><span></span><span></span><span></span></div>
    </button>

    <!-- Collapsible content -->
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav ml-auto text-center">
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/">
                <i class="iconfont icon-home-fill"></i>
                主页
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/archives/">
                <i class="iconfont icon-archive-fill"></i>
                日志
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/categories/">
                <i class="iconfont icon-category-fill"></i>
                目录
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/tags/">
                <i class="iconfont icon-tags-fill"></i>
                标签
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/about/">
                <i class="iconfont icon-user-fill"></i>
                个人
              </a>
            </li>
          
        
        
          <li class="nav-item" id="search-btn">
            <a class="nav-link" data-toggle="modal" data-target="#modalSearch">&nbsp;<i
                class="iconfont icon-search"></i>&nbsp;</a>
          </li>
        
        
          <li class="nav-item" id="color-toggle-btn">
            <a class="nav-link" href="javascript:">&nbsp;<i
                class="iconfont icon-dark" id="color-toggle-icon"></i>&nbsp;</a>
          </li>
        
      </ul>
    </div>
  </div>
</nav>

    <div class="banner" id="banner" parallax=true
         style="background: url('/img/default.png') no-repeat center center;
           background-size: cover;">
      <div class="full-bg-img">
        <div class="mask flex-center" style="background-color: rgba(0, 0, 0, 0.3)">
          <div class="page-header text-center fade-in-up">
            <span class="h2" id="subtitle" title="数据库笔记">
              
            </span>

            
              <div class="mt-3">
  
    <span class="post-meta mr-2">
      <i class="iconfont icon-author" aria-hidden="true"></i>
      Mike Taylor
    </span>
  
  
    <span class="post-meta">
      <i class="iconfont icon-date-fill" aria-hidden="true"></i>
      <time datetime="2021-05-10 18:14" pubdate>
        2021年5月10日 晚上
      </time>
    </span>
  
</div>

<div class="mt-1">
  
    
    <span class="post-meta mr-2">
      <i class="iconfont icon-chart"></i>
      23.6k 字
    </span>
  

  
    
    <span class="post-meta mr-2">
      <i class="iconfont icon-clock-fill"></i>
      
      
      248
       分钟
    </span>
  

  
  
    
      <!-- 不蒜子统计文章PV -->
      <span id="busuanzi_container_page_pv" style="display: none">
        <i class="iconfont icon-eye" aria-hidden="true"></i>
        <span id="busuanzi_value_page_pv"></span> 次
      </span>
    
  
</div>

            
          </div>

          
        </div>
      </div>
    </div>
  </header>

  <main>
    
      

<div class="container-fluid nopadding-x">
  <div class="row nomargin-x">
    <div class="d-none d-lg-block col-lg-2"></div>
    <div class="col-lg-8 nopadding-x-md">
      <div class="container nopadding-x-md" id="board-ctn">
        <div class="py-5" id="board">
          <article class="post-content mx-auto">
            <!-- SEO header -->
            <h1 style="display: none">数据库笔记</h1>
            
              <p class="note note-info">
                
                  本文最后更新于：2021年6月8日 晚上
                
              </p>
            
            <div class="markdown-body">
              <p>教材：《数据库系统原理、设计与编程》陆鑫 张凤荔 陈安龙/编著</p>
<h1 id="第一章-数据库系统基础"><a href="#第一章-数据库系统基础" class="headerlink" title="第一章 数据库系统基础"></a>第一章 数据库系统基础</h1><p>数据库技术的核心是实现信息化应用与服务的核心技术之一，它涉及数据组织与存储、数据存取模型、数据操作语言、数据架构与模型设计、数据管理与系统处理、应用数据访问编程等技术主题。</p>
<p>PostgreSQL对象-关系数据库</p>
<h2 id="1-1-数据库及其系统的概念"><a href="#1-1-数据库及其系统的概念" class="headerlink" title="1.1 数据库及其系统的概念"></a>1.1 数据库及其系统的概念</h2><h3 id="1-1-1-数据库定义"><a href="#1-1-1-数据库定义" class="headerlink" title="1.1.1 数据库定义"></a>1.1.1 数据库定义</h3><p>任何信息系统的技术实现，均需要使用具有特定数据模型的系统容器组织与存储数据，同时还需要相应的系统软件支持应用程序对系统容器中的数据进行共享操作。在计算机领域中，这类组织与存储数据的系统容器被称为“数据库”。</p>
<p>更专业的定义：</p>
<p>定义一：简单来说，数据库是一种电子化的文件柜，用户可以对文件柜中的数据进行新增、检索、更新、删除等操作。</p>
<p>定义二：数据库是以一定方式存储在一起的、能为多个用户所共享的数据集合。</p>
<p>定义三：数据库是依照某种数据模型组织起来的，并存放在存储器中的数据集合。这种数据集合有如下的特点：尽可能不重复存储数据，以优化方式为用户存取数据提供服务，其数据结构独立于它的应用程序，其数据的增删改和检索由统一软件进行管理和控制。</p>
<p>综上：我们可以将数据库理解为一种依照特定数据模型组织、存储和管理数据的文件集合。在信息系统中，数据库的基本作用是组织与存储系统数据，并为系统软件从中存取数据提供支持。</p>
<p>与文件系统中的普通数据文件明显不同，数据库文件有如下特点：</p>
<ul>
<li>数据一般不重复存放。</li>
<li>可支持多个应用程序并发访问。</li>
<li>数据结构独立于使用它的应用程序。</li>
<li>对数据的增、删、改、查操作均由数据库系统软件进行控制和管理。</li>
</ul>
<h3 id="1-1-2-数据模型"><a href="#1-1-2-数据模型" class="headerlink" title="1.1.2 数据模型"></a>1.1.2 数据模型</h3><h4 id="1-数据模型"><a href="#1-数据模型" class="headerlink" title="1.数据模型"></a>1.数据模型</h4><p>数据模型：一种描述事物对象数据特征及其结构的形式化表示，通常由<strong>数据结构、数据操作、数据约束</strong>三部分构成。</p>
<ul>
<li>数据结构：用于描述事物对象的<strong>静态特征</strong>，其中包括事物对象的属性数据、数据类型、数据组织方式等。数据结构是数据模型的<strong>基础</strong>，数据操作和约束都是基于该数据结构进行的。</li>
<li>数据操作：用于描述事物对象的<strong>动态特征</strong>，即对事物对象的属性数据可进行的数据操作，如：插入、更新、删除、查询等。在数据模型中，我们通常还需要定义数据操作语言，如操作语句、操作规则及操作结果表示。</li>
<li>数据约束：用于描述事物对象的数据之间<strong>语义的联系</strong>，以及数据取值范围等规则，从而确保数据的完整性、一致性、有效性。</li>
</ul>
<h4 id="2-数据库所使用的数据模型"><a href="#2-数据库所使用的数据模型" class="headerlink" title="2.数据库所使用的数据模型"></a>2.数据库所使用的数据模型</h4><p>传统数据库先后使用的数据模型主要有：层次数据模型、网状数据模型、关系数据模型。它们的根本区别在于<strong>数据之间的联系方式不同</strong>，即数据记录之间的联系方式不同。</p>
<p>层次数据模型，以”树结构“方式表示数据记录之间的联系。</p>
<p>网状数据模型，以”图结构“方式来表示数据记录之间的联系。</p>
<p>关系数据模型，以”二维关系表“方式表示数据之间的联系。</p>
<ul>
<li><p>层次数据模型</p>
<ul>
<li>最早使用的一种数据模型，其数据结构是一颗包含多个数据节点的”有向树“。根节点在最上端，层次最高；子节点在下层；最低层为叶节点。每个数据节点存储一个数据记录，数据节点之间通过<strong>链接指针</strong>进行联系。当需要访问层次数据模型的数据时，需要使用树节点遍历方法进行数据记录的操作。</li>
<li>特征：该模型将数据节点组织成多叉树关系的数据结构，程序采用关键字检索来遍历访问各个数据节点。</li>
<li>优点：<ul>
<li>数据结构层次清晰，使用指针遍历访问各个数据节点。</li>
<li>数据节点的更新和扩展很容易实现。</li>
<li>关键字检索查询效率高。</li>
</ul>
</li>
<li>缺点：<ul>
<li>系统数据结构局限于层次结构，缺乏灵活性。</li>
<li>相同信息的数据节点可能存储多次，数据<strong>冗余大</strong>。</li>
<li>层次数据模型不适合具有拓扑空间的数据组织。</li>
</ul>
</li>
</ul>
</li>
<li><p>网状数据模型</p>
<ul>
<li>网状数据模型以网络图表示数据节点之间的联系。该网状结构中的每一个数据节点代表一个数据记录，节点之间的联系也使用<strong>链接指针</strong>来实现，但网状结构模型可以表示数据节点之间的多个从属关系，同时也可以表示数据节点之间的横向关系。网状关系模型扩展了层次数据模型的数据关系，其数据处理更见方便。</li>
<li>特征：该模型采用链接指针来确定数据节点之间的联系，可支持具有<strong>多对多</strong>联系的数据节点组织方式。网状数据模型允许各个节点有多于一个的父节点，也可以有一个以上的节点没有父节点。</li>
<li>优点：能明确而方便地表示数据间的复杂关系，数据<strong>冗余较小</strong>。</li>
<li>缺点：<ul>
<li>结构较复杂，增加了数据查询和数据定位的困难；</li>
<li>需要存储数据间联系的指针，使得数据存储量增大；</li>
<li>数据更新不方便，除了对数据进行更新外，还必须修改关联指针。</li>
</ul>
</li>
</ul>
</li>
<li><p>关系数据模型</p>
<ul>
<li>关系数据模型（简称关系模型），以关系代数理论为基础，通过二维表结构来表示数据记录之间联系的数据模型。关系数据模型的每个二维表应具有关系特征，它们又被称为关系表。在关系数据模型中，多个二维表可以通过相同属性列的<strong>一致约束性</strong>进行数据关联。</li>
<li>优点：<ul>
<li>数据结构简单，数据操作灵活</li>
<li>支持关系与集合运算操作</li>
<li>支持广泛使用的结构化查询语言（SQL）</li>
<li>容易实现与应用程序的数据独立性</li>
</ul>
</li>
<li>缺点：<ul>
<li>局限于<strong>结构化</strong>数据组织与存储。</li>
<li>支持的数据类型较简单。</li>
<li>难以支持非结构化数据和复杂数据处理。</li>
</ul>
</li>
<li>现状：关系数据模型存取数据路径对用户隐蔽，使程序和数据具有高度的独立性。关系数据模型的数据操作语言为<strong>非过程化</strong>语言，具有集合处理能力，并能实现数据库对象的定义、操纵、控制等一体化处理。因此：<strong>关系数据模型是目前数据库使用最广泛的数据模型，几乎所有的结构化数据库管理系统产品都采用关系数据模型实现数据库</strong>。（Oracle、MySQL）</li>
</ul>
</li>
<li><p>其他数据模型（如对象关系数据模型）</p>
</li>
</ul>
<h3 id="1-1-3-数据库系统的组成"><a href="#1-1-3-数据库系统的组成" class="headerlink" title="1.1.3 数据库系统的组成"></a>1.1.3 数据库系统的组成</h3><p>数据库系统：一种基于数据库进行数据管理与信息服务的软件系统。</p>
<p>数据库应用系统：数据库在应用领域实现数据存储、数据处理、数据检索、数据分析等功能。</p>
<p>数据库系统组成：<strong>用户、数据库应用程序、数据库管理系统、数据库</strong>4部分。</p>
<h4 id="1-用户"><a href="#1-用户" class="headerlink" title="1.用户"></a>1.用户</h4><p>数据库系统中，用户可分为最终用户和DBA（DataBase Administrator）用户两类。</p>
<p>最终用户通过操作<strong>数据库应用程序</strong>处理业务，并利用程序存取数据库信息。数据库应用程序不能直接存取数据库信息，必须基于数据库管理系统（DataBase Management System，DBMS）提供的接口和环境才能访问数据库。</p>
<p>DBMA用户是一种专门进行数据库管理与运行维护的系统用户，该用户通过使用<strong>DBMS</strong>软件提供的管理工具对数据库进行创建、管理和维护，从而为数据库系统的正常运行提供支持与保护。</p>
<h4 id="2-数据库应用程序"><a href="#2-数据库应用程序" class="headerlink" title="2.数据库应用程序"></a>2.数据库应用程序</h4><p>数据库应用程序时是一种在DBMS支持下对数据库进行访问和处理的应用程序。它们<strong>以窗口和页面等表单形式来读取、更新、查询或统计数据库信息</strong>，从而实现业务数据处理与信息服务。</p>
<p>通过表单列表输出结果数据。</p>
<p>数据库应用程序需要使用DBMS提供的标准接口（如：JDBC/ODBC等）驱动程序连接数据库。</p>
<p>在程序设计语言编程中，我们需要使用数据库访问接口实现对数据库的操作。</p>
<h4 id="3-数据库管理系统DBMS"><a href="#3-数据库管理系统DBMS" class="headerlink" title="3.数据库管理系统DBMS"></a>3.数据库管理系统DBMS</h4><p>DBMS是一类用于<strong>创建、操纵和管理</strong>数据库的系统软件。数据库管理系统与操作系统一样都属于系统平台软件。</p>
<ul>
<li>DBMS一般具有如下功能：<ul>
<li><strong>创建</strong>数据库、数据库表及其他对象</li>
<li>读/写、更新、删除数据库表数据（进行<strong>数据操纵</strong>）</li>
<li>维护<strong>数据库结构</strong></li>
<li>执行数据<strong>访问规则</strong></li>
<li>提供数据库<strong>并发访问控制和安全控制</strong></li>
<li><strong>执行数据库备份和恢复</strong></li>
</ul>
</li>
</ul>
<p><strong>DBMS层次结构</strong></p>
<blockquote>
<p>数据库应用程序</p>
<blockquote>
<p>DBMS：</p>
<p>​    操作界面层：</p>
<p>​        由若干管理工具和应用程序API组成，分别为用户和应用程序访问数据库提供    接口界面。</p>
<p>​    语言翻译处理层：</p>
<p>​        对应用程序中的<strong>数据库操作语句</strong>进行语法分析、视图转换、授权检查、查询优化等处理。</p>
<p>​    数据存取层：</p>
<p>​        处理对象是<strong>数据表中的记录</strong>，他将上层的集合关系操作转换为数据记录操作，如对数据记录进行存取、维护存取路径、并发控制、事物管理、日志记录等。</p>
<p>​    数据存储层 ：基于操作系统提供的系统调用对<strong>数据库文件</strong>进行数据块读/写操作，并完成数据页、系统缓冲、内外存交换、外存数据文件等操作系统管理。</p>
</blockquote>
<p>操作系统</p>
<p>数据库文件</p>
</blockquote>
<h4 id="4-数据库"><a href="#4-数据库" class="headerlink" title="4.数据库"></a>4.数据库</h4><p>数据库系统中，数据库是存放系统各类数据的容器。该容器按照一定的数据模型组织与存储数据。目前，数据库系统使用最多的数据库软件产品是关系数据库软件。这类数据库软件采用关系数据模型实现数据组织与存储。</p>
<p>除了存放<strong>用户数据</strong>外，我们还需要存放<strong>描述数据库结构的元数据</strong>。例如：关系数据库中，各个关系表的表名称、列名称、列数据类型、数据约束规则等都是元数据，这些描述数据库结构的数据需要存放在数据库的系统表中。</p>
<ul>
<li>关系数据库存储的主要数据信息类型：<ul>
<li>用户数据</li>
<li>元数据</li>
<li>索引数据</li>
<li>其他数据</li>
</ul>
</li>
</ul>
<p>在关系数据库中，数据库元数据（必要）、索引数据、运行数据等（都是管理数据的数据），存放在<strong>系统表</strong>中，用户数据则只能存放于<strong>用户表</strong>中。</p>
<h2 id="1-2-数据库技术的发展"><a href="#1-2-数据库技术的发展" class="headerlink" title="1.2 数据库技术的发展"></a>1.2 数据库技术的发展</h2><p>数据库技术是一种利用计算机组织、存储和管理数据的软件技术。它涉及研究数据库的结构、存储、设计、管理、应用的基本理论和实现方法，并来利用这些理论对数据库中的数据进行存取、计算、统计以及分析等操作。</p>
<h3 id="1-2-1-数据管理技术的演化"><a href="#1-2-1-数据管理技术的演化" class="headerlink" title="1.2.1 数据管理技术的演化"></a>1.2.1 数据管理技术的演化</h3><p>数据库技术现已称为当今计算机软件领域发展最迅速、应用最广泛的技术。不仅应用于数据资源存取管理，还应用于信息检索、数据仓库、数据挖掘、商业智能、大数据处理等领域。在利用计算机进行数据管理的技术发展历程中，数据管理经历了人工数据管理、文件系统管理、数据库管理3个阶段。</p>
<h4 id="1-人工数据管理"><a href="#1-人工数据管理" class="headerlink" title="1.人工数据管理"></a>1.人工数据管理</h4><p>在涉及数据处理的计算机程序中，程序员必须在代码中进行数据管理。</p>
<h4 id="2-文件系统管理"><a href="#2-文件系统管理" class="headerlink" title="2.文件系统管理"></a>2.文件系统管理</h4><p>操作系统出现后，可使用数据文件方式来组织、存储数据，并采用文件系统工具管理各个独立的数据文件。文件系统可以按照数据文件的名称对其进行访问，既可对数据文件中的数据记录进行存取，也可以对数据记录进行更新、插入、删除。文件系统实现了数据在记录内的结构化，即在数据文件的各个记录中，数据项组成是一致的。但是从整体看数据文件，数据记录之间是无结构的，不能处理数据记录之间的关联性。</p>
<p>用户可以使用高级程序语言对数据文件进行数据记录的存取，解决了人工数据管理的限制，可以满足应用的基本数据管理要求。</p>
<ul>
<li>不足：<ul>
<li>编写应用程序管理数据的过程比较繁琐。–繁琐</li>
<li>数据文件对应用程序存在依赖，难以实现独立。–不独立</li>
<li>不支持多用户对数据文件并发访问。–无法并发访问</li>
<li>不能实现数据文件的安全控制。–无法安全控制</li>
<li>难以解决不同数据文件之间的数据冗余。–数据冗余</li>
<li>在文件中，数据记录之间缺少联系，难以满足用户对数据的关联访问。–数据关联性差</li>
</ul>
</li>
</ul>
<h4 id="3-数据库管理（实现了数据共享）"><a href="#3-数据库管理（实现了数据共享）" class="headerlink" title="3.数据库管理（实现了数据共享）"></a>3.数据库管理（实现了数据共享）</h4><p>DBMS出现，在这个阶段，用户可以使用DBMS来实现应用系统的数据管理。应用程序连接数据库后，用户可以使用数据库操作语言对其表中数据进行操作。所有对数据库的操作都由数据库管理DBMS自动去完成，应用程序不需要考虑数据库文件的物理操作和系统控制。</p>
<ul>
<li>数据库管理与文件数据管理比，有如下优点：<ul>
<li>应用程序与数据相互独立，避免了应用程序对数据的依赖性。</li>
<li>应用程序访问数据库使用标准语言操作，编程访问简单。</li>
<li>数据组织结构化、共享性高、冗余小。</li>
<li>提供数据的安全访问机制，并保证数据的完整性、一致性、正确性。</li>
</ul>
</li>
</ul>
<h3 id="1-2-2-数据库技术的发展阶段"><a href="#1-2-2-数据库技术的发展阶段" class="headerlink" title="1.2.2 数据库技术的发展阶段"></a>1.2.2 数据库技术的发展阶段</h3><p><strong>数据模型是数据库技术的核心</strong>，数据模型的发展演变可以作为数据库技术发展阶段的主要标志。</p>
<ul>
<li>数据库技术主要经历了三代：<ul>
<li>第一代：<strong>层次数据模型和网状数据模型</strong>为特征的数据库技术。</li>
<li>第二代：<strong>关系数据模型</strong>为特征的数据库技术。</li>
<li>第三代：以<strong>面向数据对象数据模型</strong>为主要特征的数据库技术。</li>
<li>目前第四代：数据库技术与计算机网络技术、人工智能技术、并行计算技术、多媒体技术、云计算技术、大数据技术等相互结合与相互促进，衍生出大量的数据库新技术，其典型特征是采用非结构化数据模型处理大数据。</li>
</ul>
</li>
</ul>
<h3 id="1-2-3-数据库领域新技术"><a href="#1-2-3-数据库领域新技术" class="headerlink" title="1.2.3 数据库领域新技术"></a>1.2.3 数据库领域新技术</h3><h4 id="1-NoSQL技术"><a href="#1-NoSQL技术" class="headerlink" title="1.NoSQL技术"></a>1.NoSQL技术</h4><p>现在大量互联网应用数据以非结构化形式存在，如：网页信息、文档信息、报表信息、音视频信息、即时通信消息等。海量的非结构化数据时刻都在进行结构化处理，势必带来系统对信息数据处理的开销和时效性不满足需求的问题。NoSQL数据库技术是一类针对大量互联网应用的<strong>非结构化数据处理需求</strong>而产生的一种<strong>分布式非关系数据库技术</strong>。它突破了传统关系数据库结构中必须等长存储各记录行数据的限制，它支持重复字段、子字段以及变长字段，并可以实现对变长数据和重复数据类型进行处理，在处理各类文档、报表、图像、音视频等非结构化数据中有着传统关系数据库所无法比拟的优势。因此，NoSQL数据库技术称为成为支持大数据应用的数据管理主流技术。</p>
<h4 id="2-NewSQL技术"><a href="#2-NewSQL技术" class="headerlink" title="2.NewSQL技术"></a>2.NewSQL技术</h4><p>虽然NoSQL数据库技术可以有效解决非结构化数据存储与大数据操作，具有良好的扩展性和灵活性，但不支持广泛使用的结构化数据访问SQL，也不支持数据库事物的ACID（原子性、一致性、隔离性、持久性）特性操作。另外，不同的NoSQL数据库都有各自的查询语言和数据模型，这使得开发者很难规范应用程序接口。因此，NoSQL数据库技术仅解决了互联网应用的非结构化数据处理需求，但对于企业应用的结构化数据管理并不合适。</p>
<p>NewSQL数据库技术是一种在NoSQL技术的基础上同时支持关系数据库访问的技术，这类数据库具有NoSQL对海量数据的分布式存储管理能力，还保持了兼容传统关系数据库的ACID和SQL等特性。NewSQL数据库技术不但支持非结构化数据管理的大数据应用，也支持结构化数据管理的关系数据库应用，它将成为未来主流的数据库技术。</p>
<h4 id="3-领域数据库"><a href="#3-领域数据库" class="headerlink" title="3.领域数据库"></a>3.领域数据库</h4><p>针对特定领域开发。数据库应用领域先后出现：工程数据库，统计数据库、科学数据库、空间数据库、地理信息数据库等。这些领域数据库在技术实现原理上与通用的数据库没有多大区别，只是与特定的领域结合，加强了数据库系统对有关领域的紧密结合。</p>
<h4 id="4-数据仓库与数据挖掘"><a href="#4-数据仓库与数据挖掘" class="headerlink" title="4.数据仓库与数据挖掘"></a>4.数据仓库与数据挖掘</h4><p>数据库技术不局限于操作型数据库领域，对大量应用的历史数据进行有效存储与联机分析，已成为机构信息服务的重要需求。</p>
<p>数据仓库(Data Warehouse)：数据库已经存储了很长时间的数据的情况下，需要对积累的大量历史数据进行有效的存储组织，以便实现决策分析所需要的联机分析与数据挖掘处理。</p>
<p>数据仓库数据来自于若干分散的操作型数据库，管理具有面向主题、集成性、稳定性、时变性等特征。在数据仓库中，主要工作是对历史数据进行大量的查询操作或联机统计分析处理，以及定期的数据加载、刷新，很少进行数据更新和删除操作。</p>
<p>数据挖掘：建立在数据仓库的基础上，对大量数据进行模式或规律挖掘，从中发现有价值信息的技术。</p>
<p>数据挖掘一般包含3个步骤：<strong>数据预处理、规律寻找、结果可视化</strong>。数据预处理是从相关数据源中选取所需的数据并整合成用于数据挖掘的数据集；规律寻找，用某种方法将数据集合所含规律找出来；结果可视化，表示尽可能以用户可以理解的方式将规律表示出来。</p>
<h4 id="5-商业智能"><a href="#5-商业智能" class="headerlink" title="5.商业智能"></a>5.商业智能</h4><p>定义：一种利用现代数据仓库技术、联机分析处理技术、数据挖掘等技术对商业信息系统中积累的大量数据进行数据分析以实现商业价值的技术。</p>
<p>商业智能主要包括对商业信息的搜集、管理和分析过程，目的是使商业机构的各级决策者获得商业运营信息或规律洞察力，促使他们做出对机构更有利的决策。基本体系结构包括：<strong>数据仓库、联机分析处理、数据挖掘</strong>。</p>
<p>辅助商业决策。</p>
<h4 id="6-大数据分析处理技术（只有它能处理非结构化数据）"><a href="#6-大数据分析处理技术（只有它能处理非结构化数据）" class="headerlink" title="6.大数据分析处理技术（只有它能处理非结构化数据）"></a>6.大数据分析处理技术（只有它能处理非结构化数据）</h4><p>传统的数据挖掘和商业智能处理的数据类型有限，不能快速处理海量的非结构化数据。</p>
<p>大数据：数据规模以及复杂性难以用传统数据管理软件以合理成本及可以接受的时限对其进行数据分析的数据集。</p>
<p>对比已有数据分析处理技术，大数据分析处理技术具有快速、廉价、性能强等综合优势。</p>
<h4 id="讨论："><a href="#讨论：" class="headerlink" title="讨论："></a>讨论：</h4><ul>
<li><p>关系数据库不适合大数据应用处理，由于大数据应用处理针对非结构化数据，这些数据无法二维表化。</p>
</li>
<li><p>结构化数据与非结构化数据区别：能否二维表化</p>
</li>
<li><p>NoSQL与NewSQL的区别：NoSQL支持非关系数据库访问，NewSQL支持结构化和非结构化数据库访问。</p>
</li>
</ul>
<h2 id="1-3-数据库应用系统"><a href="#1-3-数据库应用系统" class="headerlink" title="1.3 数据库应用系统"></a>1.3 数据库应用系统</h2><p>数据库应用系统：借助数据库进行信息化处理的计算机应用系统。</p>
<h3 id="1-3-1-数据库应用数据的类型"><a href="#1-3-1-数据库应用数据的类型" class="headerlink" title="1.3.1 数据库应用数据的类型"></a>1.3.1 数据库应用数据的类型</h3><ul>
<li>业务处理系统<ul>
<li>定义：运用数据库应用程序对机构日常业务活动信息进行记录、计算、检索、汇总、统计等数据处理，为机构操作层面提供业务信息化处理服务，提高业务处理效率的信息系统。</li>
<li>业务处理系统处理分为：联机业务处理和业务延迟批处理。</li>
</ul>
</li>
<li>管理信息系统<ul>
<li>定义：一种以机构职能管理为目标，利用计算机软硬件、网络通信、数据库等IT技术，实现机构职能整体信息化管理，以达到规范化管理和提高机构工作效率，并支持机构职能服务的信息系统。</li>
</ul>
</li>
<li>决策支持系统<ul>
<li>定义：以管理科学、运筹学、控制论、行为科学为基础，以计算机技术、数据库技术、人工智能技术为手段，解决特定领域的决策管理问题，为管理者提供辅助决策服务和方案的信息系统。</li>
</ul>
</li>
</ul>
<h3 id="1-3-2-数据库应用系统的结构"><a href="#1-3-2-数据库应用系统的结构" class="headerlink" title="1.3.2 数据库应用系统的结构"></a>1.3.2 数据库应用系统的结构</h3><ul>
<li><p>单用户结构</p>
<ul>
<li><p>数据库应用系统服务对象为单个用户，应用系统软件和数据库安装在一台计算机上运行。</p>
</li>
<li><p>特点：单用户结构中，数据库应用系统的各个部件都部署在一台计算机上，一个用户进行应用功能操作，并获得数据处理服务。</p>
</li>
<li><p>优缺点：结构简单，易于维护，但是只适用于单用户使用，不能实现用户之间数据的共享和交换。</p>
</li>
</ul>
</li>
<li><p>集中式结构</p>
<ul>
<li>一些多终端业务系统中，<strong>应用程序、数据库及其DBMS</strong>安装于同一台服务器上运行，而用户则使用自己的客户端计算机或智能手机通过网络连接访问服务器系统，<strong>业务服务系统的所有处理操作都是在服务器集中处理</strong>。</li>
<li>特点：数据库应用系统的数据集中、处理集。支持多个用户并发访问服务器系统，能够实现用户之间的数据共享。</li>
<li>优缺点：可利用服务器实现集中计算、结构简单、易于维护，但是当终端用户增加到一定数量后，服务器响应客户机请求访问将会成为瓶颈，系统处理性能大大降低。</li>
</ul>
</li>
<li><p>客户/服务器结构</p>
<ul>
<li><p><strong>应用系统的处理逻辑分布在客户机和服务器</strong>中，各个计算机分担处理系统逻辑，如：服务器运行数据库和DBMS，客户机运行处理应用程序的逻辑。</p>
</li>
<li><p>数据库服务器：专门用于运行DBMS软件以及数据库的服务器。</p>
<p>客户机：运行计算机应用程序的计算机。</p>
</li>
<li><p>客户端应用程序将数据访问请求传送到数据库服务器；数据库服务器接受请求，对数据库进行数据操作处理，并将数据操作结果返回给客户端应用程序。</p>
</li>
<li><p>特点：数据库应用系统的数据集中管理、应用分布处理。客户端应用程序通过网络并发访问数据库服务器数据库。</p>
</li>
<li><p>优缺点：客户/服务器模式的数据库应用系统通过各个计算机分担处理任务，可提高整个系统的处理能力，但当客户机节点很多时，其网络与数据库服务器都可能成为系统性能瓶颈。</p>
</li>
</ul>
</li>
<li><p>分布式结构</p>
<ul>
<li>数据库系统由分布在多个服务器运行的数据库节点构成。分布式数据库管理系统提供了有效的一致性存取手段来操纵这些节点上的数据库，使这些分布的数据库在逻辑上可被视为一个完整的数据库，而物理上它们是地理分散在各个服务器节点的数据库。</li>
<li>特点：<strong>分布式结构既实现数据分布，又实现处理分布</strong>。在分布式结构中，各服务器处理节点数据库在逻辑上是一个整体，但物理分布在计算机网络的不同服务器节点上运行。每个数据库服务器可通过网络既支持多个本地客户机访问，也支持远程客户访问，网络中的每个数据库可以独立地存取与处理数据，并执行全局应用。</li>
<li>优缺点：适应跨地区的大型机构和企业等组织对数据库应用的需求，其处理性能强，但数据库分布处理与维护有一定的开销和技术困难。</li>
</ul>
</li>
</ul>
<h3 id="1-3-3-数据库应用系统生命周期"><a href="#1-3-3-数据库应用系统生命周期" class="headerlink" title="1.3.3 数据库应用系统生命周期"></a>1.3.3 数据库应用系统生命周期</h3><p>按软件工程思想，其生命周期可分为：系统需求设计、系统设计、系统实现、系统测试、系统运行维护等阶段。</p>
<h4 id="1-系统需求设计"><a href="#1-系统需求设计" class="headerlink" title="1.系统需求设计"></a>1.系统需求设计</h4><p>系统分析人员与用户交流，按照需求工程方法获取系统数据需求信息。采用需求模型定义系统数据组成。</p>
<ul>
<li>需求信息收集<ul>
<li>由高层到低层展开</li>
</ul>
</li>
<li>需求信息分析<ul>
<li>采用面向对象分析方法或结构化分析方法建模，描述业务流程以及业务数据联系形式。</li>
</ul>
</li>
<li>系统需求规格说明<ul>
<li>定义详尽数据字典。</li>
</ul>
</li>
</ul>
<h4 id="2-系统设计"><a href="#2-系统设计" class="headerlink" title="2.系统设计"></a>2.系统设计</h4><p>在数据库应用系统设计阶段，系统设计人员依据系统需求档案，开展系统总体设计和详细设计。设计内容包括：系统架构设计、软件功能结构设计、功能模块化设计、功能模块逻辑设计、系统数据库设计、系统接口设计。</p>
<p>系统数据库设计又分为<strong>概念数据模型、逻辑数据模型、物理数据模型设计</strong>。</p>
<h4 id="3-系统实现"><a href="#3-系统实现" class="headerlink" title="3.系统实现"></a>3.系统实现</h4><p>按照系统设计方案进行数据库应用系统编程实现，分别进行软件程序编写、DBMS安装部署、数据库创建和数据对象实现等方面的工作。</p>
<ul>
<li>创建数据库对象<ul>
<li>用DBMS提供的数据语言DDL编写出数据库的源模式，经编译得到目标模式，执行目标模式即可建立实际数据库对象。</li>
</ul>
</li>
<li>载入测试数据</li>
</ul>
<h4 id="4-系统测试"><a href="#4-系统测试" class="headerlink" title="4.系统测试"></a>4.系统测试</h4><p>针对数据库测试，则是依据数据库设计规范对软件系统的数据库结构、数据表及其之间的数据约束关系进行测试。</p>
<h4 id="5-系统运行与维护"><a href="#5-系统运行与维护" class="headerlink" title="5.系统运行与维护"></a>5.系统运行与维护</h4><ul>
<li>维护数据库系统安全性与完整性</li>
<li>监控与优化数据库系统运行性能</li>
<li>扩展数据库系统处理能力</li>
</ul>
<h4 id="思考："><a href="#思考：" class="headerlink" title="思考："></a>思考：</h4><p>数据库表对象的创建是在哪个工作阶段？（系统实现阶段）</p>
<h2 id="1-4-典型数据库管理系统"><a href="#1-4-典型数据库管理系统" class="headerlink" title="1.4 典型数据库管理系统"></a>1.4 典型数据库管理系统</h2><ul>
<li>Microsoft SQL server<ul>
<li>基于关系数据模型</li>
</ul>
</li>
<li>Oracle DataBase</li>
<li>MySQL<ul>
<li>开源关系数据库管理系统，桌面级</li>
</ul>
</li>
<li>PostgreSQL：开源对象-关系数据库管理系统</li>
</ul>
<h2 id="1-5-PostgreSQL-对象-关系数据库系统软件"><a href="#1-5-PostgreSQL-对象-关系数据库系统软件" class="headerlink" title="1.5 PostgreSQL 对象-关系数据库系统软件"></a>1.5 PostgreSQL 对象-关系数据库系统软件</h2><ul>
<li>PostgreSQL服务器端程序<ul>
<li>initdb：创建一个新的PostgreSQL数据库簇(Cluster)</li>
<li>pg_controldata：显示一个PostgreSQL数据库集群的控制信息</li>
<li>pg_ctl：初始化、启动、停止控制PostgreSQL服务器。</li>
<li>pg_resetxlog：重置一个数据库集群的预写日志和其他控制内容。</li>
<li>postgres：数据库服务器服务进程。</li>
<li>postmaster：数据库服务守护进程。</li>
</ul>
</li>
</ul>
<p>管理工具：psql命令行工具   pgAdmin图形界面管理工具</p>
<ul>
<li>PostgreSQL数据库对象：<ul>
<li>schema<ul>
<li>通常含系统默认创建的schema和用户自己创建的schema</li>
<li>属于某个数据库</li>
</ul>
</li>
<li>table<ul>
<li>属于某个schema</li>
</ul>
</li>
<li>view</li>
<li>序列（Sequence）</li>
<li>Function</li>
<li>Trigger</li>
</ul>
</li>
</ul>
<h2 id="1-6-学堂在线"><a href="#1-6-学堂在线" class="headerlink" title="1.6 学堂在线"></a>1.6 学堂在线</h2><ul>
<li><p>在数据管理技术发展阶段中，下面哪个阶段可以实现数据共享？</p>
<p>数据库管理阶段</p>
</li>
<li><p>Microsoft SQL Server数据库是属于下面哪种模型数据库？</p>
<p>关系数据模型</p>
</li>
<li><p>在数据库管理系统的层次结构中，下面哪个层次负责对数据文件进行操作访问？</p>
<p>数据存储层</p>
</li>
<li><p>在数据库领域技术中，下面哪种技术可以实现数据集成？</p>
<p>数据仓库技术</p>
</li>
<li><p>下面哪种数据库系统应用结构适合银行业务系统？</p>
<p>分布式结构</p>
</li>
<li><p>下面哪类数据库应用系统需要使用数据分析处理技术？</p>
<p>决策支持系统</p>
</li>
<li><p>下面哪类数据库管理系统是对象-关系数据库系统？</p>
<p>PostgreSQL</p>
</li>
<li><p>下面哪个程序实现PostgreSQL服务器起停控制？</p>
<p>pg_ctl</p>
</li>
<li><p>在PostgreSQL数据库中，不包含下面哪种数据库对象？</p>
<p>存储过程</p>
</li>
<li><p>在PostgreSQL数据库中，不包含下面哪种类型表？</p>
<p>索引表</p>
</li>
<li><p>用户程序可以直接访问数据库</p>
<p>❌</p>
</li>
<li><p>在数据库系统中，可以保证没有冗余数据。</p>
<p>❌</p>
</li>
<li><p>业务规则数据在数据库中是一种元数据。</p>
<p>✔</p>
</li>
<li><p>面向对象数据库可以支持复杂数据类型处理，它一定会取代关系数据库。</p>
<p>❌</p>
</li>
<li><p>NoSQL数据库可以管理非结构化数据。</p>
<p>✔</p>
</li>
<li><p>数据库挖掘可建立在数据仓库基础上进行数据分析处理。</p>
<p>✔</p>
</li>
<li><p>为简化数据库开发，不需要数据模型设计，可直接定义数据库表。</p>
<p>❌</p>
</li>
<li><p>所有业务处理系统都支持联机事务处理和脱机事务处理。</p>
<p>❌</p>
</li>
<li><p>分布式数据库系统可实现数据分布和处理分布。</p>
<p>✔</p>
</li>
<li><p>MySQL数据库系统是一种企业级DBMS。</p>
<p>❌</p>
</li>
</ul>
<h1 id="第二章-数据库关系模型"><a href="#第二章-数据库关系模型" class="headerlink" title="第二章 数据库关系模型"></a>第二章 数据库关系模型</h1><h1 id="第三章-数据库操作语言SQL"><a href="#第三章-数据库操作语言SQL" class="headerlink" title="第三章 数据库操作语言SQL"></a>第三章 数据库操作语言SQL</h1><h1 id="第四章-数据库设计与实现"><a href="#第四章-数据库设计与实现" class="headerlink" title="第四章  数据库设计与实现"></a>第四章  数据库设计与实现</h1><h1 id="第五章-数据库管理"><a href="#第五章-数据库管理" class="headerlink" title="第五章 数据库管理"></a>第五章 数据库管理</h1><h2 id="5-1-数据库管理概述"><a href="#5-1-数据库管理概述" class="headerlink" title="5.1 数据库管理概述"></a>5.1 数据库管理概述</h2><p>数据库管理（Database Management）定义：为保证数据库系统的正常运行和服务质量必须进行的系统管理。<br>数据库管理人员（Database Administrator）：负责数据库系统管理任务的人员。</p>
<h3 id="5-1-1-数据库管理的目标和内容"><a href="#5-1-1-数据库管理的目标和内容" class="headerlink" title="5.1.1 数据库管理的目标和内容"></a>5.1.1 数据库管理的目标和内容</h3><ul>
<li>数据库使用过程面临的问题：<ul>
<li>数据库系统随规模增大,系统会变得异常复杂。</li>
<li>多用户数据库应用带来数据库访问复杂性。</li>
<li>数据安全和数据隐私对机构和用户都非常重要。</li>
<li>数据库系统随数据量增加和使用时间增长其性能会降低。</li>
<li>系统遭遇意外事件，数据库损坏或数据丢失。</li>
</ul>
</li>
<li>数据库管理的目标：<ul>
<li>保障数据库系统正常稳定运行。</li>
<li>充分发挥数据库系统的软硬件处理能力。</li>
<li>确保数据库系统安全和用户数据隐私性。</li>
<li>有效管理数据库用户及其角色权限。</li>
<li>解决数据库系统性能优化、系统故障与数据损坏等问题。</li>
<li>最大程度地发挥数据库对其所属机构的作用。</li>
</ul>
</li>
</ul>
<h3 id="5-1-2-数据库管理工具（略）"><a href="#5-1-2-数据库管理工具（略）" class="headerlink" title="5.1.2 数据库管理工具（略）"></a>5.1.2 数据库管理工具（略）</h3><p>pgAdmin、Navicat Premium、Oracel SQL Developer、MySQL Workbench等。</p>
<p>！！！！！！！</p>
<p><a href="https://imgtu.com/i/gN1Wzn"><img src="https://z3.ax1x.com/2021/05/10/gN1Wzn.png" srcset="/img/loading.gif" alt="gN1Wzn.png"></a></p>
<p>DBMS功能：</p>
<ul>
<li>数据库定义：DBMS提供DBA对数据库及其对象（表、索引、视图、约束、主键、外键等）进行创建与修改的功能。DBA可以通过DBMS执行数据定义语句（DDL）语句完成各种数据库对象的创建、修改、删除等功能处理，也可以通过DBMS管理工具的GUI操作完成这些功能处理。</li>
<li>数据库运行管理：DBMS提供DBA对数据库运行控制管理功能，主要包括数据库实例的运行<strong>启停控制</strong>、多用户环境下事务<strong>并发控制</strong>、数据库<strong>事务管理</strong>、访问操作<strong>安全性检查</strong>、访问操作存取控制（<strong>安全性控制</strong>）、访问操作<strong>完整性检查</strong>、系统运行<strong>日志管理</strong>、系统运行<strong>性能监控</strong>等管理功能。使用这些管理功能可以保证数据库系统的正常运行。数据库运行管理主要是通过DBMS管理工具完成。</li>
<li>数据的组织与存储：DBMS实现数据库的<strong>数据组织</strong>与存储管理，主要包括数据库文件组织、数据分区存储、数据索引组织、<strong>数据存取</strong>管理、<strong>缓冲区管理</strong>、存取路径管理等功能。DBA使用这些管理功能可以确保存储空间利用率和数据存取效率。数据组织与存储管理主要通过使用DBMS管理工具操作完成。</li>
<li>数据库维护：DBMS为DBA提供数据库维护管理功能，主要包括数据库文件组织、数据导出、数据库<strong>重构</strong>、数据库<strong>备份</strong>、数据库<strong>恢复</strong>、数据库<strong>性能优化</strong>等管理功能。DBA使用这些管理功能可以保障数据库系统正常高效运行。数据库维护管理主要通过DBMS管理工具操作完成。</li>
<li>数据库通信：DBMS为DBA提供数据库通信功能，主要包括数据库客户端与数据服务器连接、不同数据库之间的<strong>数据复制</strong>、不同分区之间<strong>数据同步</strong>等管理功能。DBA使用这些管理功能可以确保<strong>数据库连接</strong>、访问通信，以及分布式数据库的数据一致性。数据库通信管理主要通过使用DBMS管理工具操作完成，也可以通过DBMS编程接口完成。</li>
</ul>
<h3 id="5-1-4-DBMS结构"><a href="#5-1-4-DBMS结构" class="headerlink" title="5.1.4 DBMS结构"></a>5.1.4 DBMS结构</h3><p>！！！！！！！！！！！！！</p>
<p><a href="https://imgtu.com/i/gNGAqP"><img src="https://z3.ax1x.com/2021/05/10/gNGAqP.png" srcset="/img/loading.gif" alt="gNGAqP.png"></a></p>
<p>数据库系统中，应用程序、数据库管理工具、查询工具<strong>都需要</strong>通过访问接口访问DBMS。在接口通信中，客户端传送SQL语句/操作命令，DBMS执行SQL语句和管理命令，实现对数据库的操作与管理。同时，<strong>DBMS本身还需要通过操作系统的系统调用，才能实现对数据库文件的存取访问。</strong>DBMS对数据库操作的处理结果或读取数据也将通过接口返回客户端。<strong>所有数据库访问操作和管理操作均需要通过这些接口来实现调用控制和消息传送</strong>。除管理工具与接口外，DBMS本身由三部分组成：</p>
<ul>
<li>语言翻译层：包括SQL语句编译、视图转换、授权检查、完整性检查、事物命令解释等功能模块。</li>
<li>数据存取控制层：负责上层翻译处理的SQL命令的执行，对各种数据库对象进行逻辑存取操作访问，并实现多用户并发访问控制、数据库事务管理、执行引擎操作、权限控制、系统日志管理、数据库恢复管理、性能监控等功能操作。本层各个功能模块<strong>处理结果的结果数据和状态将返回语言翻译处理层。</strong></li>
<li>数据存储管理层：负责对数据库对象的文件、索引、记录进行物理存取操作访问，并对数据块与系统缓冲区进行管理，<strong>通过操作系统的系统接口调用接口对数据库文件进行I/O操作</strong>。本层各个功能模块<strong>处理结果数据和状态将返回数据存取控制层</strong>。</li>
</ul>
<h2 id="5-2-事物管理"><a href="#5-2-事物管理" class="headerlink" title="5.2 事物管理"></a>5.2 事物管理</h2><p>采用事务管理机制来约束并发用户程序的数据访问操作，确保并发用户程序访问操作数据库对象后，数据库仍能保持正确状态和数据一致性。</p>
<h3 id="5-2-1-事务的概念"><a href="#5-2-1-事务的概念" class="headerlink" title="5.2.1 事务的概念"></a>5.2.1 事务的概念</h3><p><strong>事务（Transaction）：指由构成单个业务处理单元的一组数据库访问操作，要求它们要么都成功执行，要么都不执行。</strong></p>
<p>目的：为了在多用户环境中事务程序共享访问数据库对象时，DBMS确保数据库处于正常状态与数据一致性。</p>
<p>例：客户在银行系统中，从账户A转账1000元到账户B，其业务操作流程如下：</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs SQL">Read (A);<br>A:<span class="hljs-operator">=</span>A<span class="hljs-number">-1000</span>;<br>Write (A);<br>Read (B);<br>B:<span class="hljs-operator">=</span>B<span class="hljs-operator">+</span><span class="hljs-number">1000</span>;<br>Write (B)<br></code></pre></td></tr></table></figure>

<p>要求：转账业务处理程序（转账事务）的操作语句要么所有都正常执行，要么所有操作语句都不执行，以确保账户资金数据的正确状态。</p>
<p><strong>在数据库系统中，事务是DBMS执行的最小任务单元。同时，事务也是DBMS最小的故障恢复任务单元和并发控制任务单元。</strong></p>
<p>数据库事务程序是实现特定业务功能处理的一组数据库操作语句序列，它们构成一个不可分割的工作单元，要么完整地被执行，要么完全不执行。</p>
<p>关系数据库中，一个事务程序可以由一条SQL语句组成，也可以由一组SQL语句组成。一个数据库应用程序可以包含一个事务程序，也可以包含多个事务程序（<strong>数据库应用程序》事务程序》SQL语句</strong>）</p>
<p>事务具有生命周期，DBMS自动记录每个事务的生命周期状态。下面是事务生命周期状态变迁图。<br><a href="https://imgtu.com/i/gNaoes"><img src="https://z3.ax1x.com/2021/05/10/gNaoes.png" srcset="/img/loading.gif" alt="gNaoes.png"></a></p>
<p>事务初始状态：事务被DBMS调度执行完成后。<br>事务正常状态：事务的SQL语句被执行成功。<br>事务提交状态：SQL语句都执行成功，事务将执行提交（Commit）操作语句。在该状态下，系统将所有操作语句对数据的修改都更新到数据库文件当中，并<strong>将所有数据操作记录到数据库事务日志(Log)文件中</strong>，以便数据库故障时，事务所做的更新操作能通过日志数据进行恢复。<br>提交/回滚完成后，事务程序退出并结束。<br>事务失败状态：<strong>即使进入事务正常状态，仍可能遇到意外事件导致事务中的某SQL语句执行失败</strong>。<br>事务回滚：事务失败状态下，事务将执行回滚（RollBack）操作语句，进入事务回滚状态。回滚状态下，系统撤销该事务对数据库所有的数据修改或删除操作，使数据库恢复到事务执行之前的数据状态。</p>
<h3 id="5-5-2-事务的特性"><a href="#5-5-2-事务的特性" class="headerlink" title="5.5.2 事务的特性"></a>5.5.2 事务的特性</h3><p>为了<strong>确保数据库共享访问的数据正确性</strong>，要求DBMS的事务管理机制维护事务的ACID特性。</p>
<ul>
<li><p>事务ACID特性：</p>
<ul>
<li>原子性（Atomicity）：事务所有操作在数据库中要么全部执行，要么全部不执行。</li>
<li>一致性（Consistency）：事务多次执行，其结果应一致。</li>
<li>隔离性（Isolation）：事务与事务之间隔离，并发执行透明。</li>
<li>持续性（Durability ）：事务完成后，数据改变必须是永久的。</li>
</ul>
</li>
<li><p>事务并发执行：指多个事务程序在数据库系统中同一时段运行。</p>
<ul>
<li>事务并发执行原因：<ul>
<li>改善系统的资源利用率</li>
<li>减少事务运行的平均等待时间</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="5-2-4-事务SQL语句"><a href="#5-2-4-事务SQL语句" class="headerlink" title="5.2.4 事务SQL语句"></a>5.2.4 事务SQL语句</h3><p>在关系数据库系统中，可以利用SQL语言提供的相应语句编写事务程序。</p>
<ul>
<li>事务SQL语句：<ul>
<li>BEGIN 或 START TRANSACTION ；事务开始语句</li>
<li>ROLLBACK ；事务回滚语句</li>
<li>COMMIT ；事务提交语句</li>
<li>SAVEPOINT ；事务保存点语句（用于事务中部分SQL操作结果保存，即：<strong>将本语句之前的数据修改保存到数据文件中，以便事务回滚时，仅取消保存点后面的数据更改操作</strong>。）</li>
</ul>
</li>
</ul>
<p>基本框架：</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><code class="hljs SQL"><span class="hljs-keyword">START</span> TRANSACTION；<br><span class="hljs-keyword">SQL</span>语句<span class="hljs-number">1</span>；<br><span class="hljs-keyword">SQL</span>语句<span class="hljs-number">2</span>；<br>…<br><span class="hljs-keyword">SQL</span>语句n；<br><span class="hljs-keyword">COMMIT</span>; <br><br><span class="hljs-keyword">START</span> TRANSACTION；<br><span class="hljs-keyword">SQL</span>语句<span class="hljs-number">1</span>；<br><span class="hljs-keyword">SQL</span>语句<span class="hljs-number">2</span>；<br>…<br><span class="hljs-keyword">SQL</span>语句n；<br><span class="hljs-keyword">ROLLBACK</span>;<br><br><span class="hljs-keyword">START</span> TRANSACTION；<br><span class="hljs-keyword">SQL</span>语句<span class="hljs-number">1</span>；<br><span class="hljs-keyword">SQL</span>语句<span class="hljs-number">2</span>；<br>…<br><span class="hljs-keyword">SAVEPOINT</span>  保存点名；<br>…<br><span class="hljs-keyword">SQL</span>语句n；<br><span class="hljs-keyword">ROLLBACK</span>  保存点名;<br><br><br></code></pre></td></tr></table></figure>

<p>事务处理语句要求：仅能使用<strong>DML或者DQL类型</strong>SQL语句（如INSERT、UPDATE、DELETE、SELECT），不能使用<strong>DDL</strong>类型语句，因为这类操作语句会<strong>自动提交，导致事务中断</strong>。</p>
<ul>
<li>不能使用的语句示例：<ul>
<li>创建数据库 CREATE DATABASE</li>
<li>修改数据库 ALTER DATABASE</li>
<li>删除数据库 DROP DATABASE</li>
<li>恢复数据库 RESTORE DATABASE</li>
<li>加载数据库 LOAD DATABASE</li>
<li>备份日志文件 BACKUP LOG</li>
<li>恢复日志文件 RESTORE LOG</li>
<li>授权操作 GRANT</li>
</ul>
</li>
</ul>
<p>若用户没有显式地定义事务时，DBMS按默认事务方式处理，即<strong>每执行一个SQL语句将自动构成一个事务</strong>。若将多条SQL语句定义为一个事务时，才使用专门的事务SQL语句显式地定义事务。</p>
<h2 id="5-3-并发控制-——事务调度"><a href="#5-3-并发控制-——事务调度" class="headerlink" title="5.3 并发控制 ——事务调度"></a>5.3 并发控制 ——事务调度</h2><p>当多个事务程序在DBMS系统中同时运行时，可能会出现对一些共享数据同时进行访问操作，如一些事务修改数据，另一些事务读取数据。<strong>这些并发的共享数据操作，如果在DBMS中没有一定的约束控制情况下，可能会带来数据不一致性或事务程序死锁问题</strong>。因此，在多个事务并发运行时，必须进行并发控制处理。</p>
<ul>
<li><strong>并发控制</strong><ul>
<li>定义：在DBMS运行多个并发事务程序时，为确保各个事务独立正常运行，并防止相互干扰、保持数据一致性，所采取的控制与管理。</li>
<li>目的：<ul>
<li>支持并发事务处理，使更多用户并行操作，提高系统的并发访问能力。</li>
<li>保证一个事务工作不会对另一个事务工作产生不合理的影响。</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="5-3-1-并发控制问题"><a href="#5-3-1-并发控制问题" class="headerlink" title="5.3.1 并发控制问题"></a>5.3.1 并发控制问题</h3><p>数据不一致问题：包括脏读、不可重复读、幻像读、丢失更新。</p>
<ul>
<li>脏读(Dirty Read)：多个事务并发运行，并操作访问共享数据，其中一个事务读取了被另一个事务所修改后的共享数据，但修改数据的事务因某种原因失败，数据未被提交到数据库文件，而读取共享数据的事务则获得一个垃圾数据，即脏数据。<ul>
<li>脏数据：对未提交数据的修改数据的统称。</li>
<li>A修改后未提交，B读取了A修改后的数据，然后A回滚（A读一次）</li>
</ul>
</li>
<li>不可重复读(Unrepeatable Read)：一个事务对同一共享事务先后重复读取两次，但是发现原有数据改变或丢失。<ul>
<li>原因：多个并发事务运行时，一些事务对共享数据进行多次读操作，但其中一个事务对共享数据进行了<strong>修改或删除</strong>等操作。</li>
<li>A读一次，B删除/修改该数据，A再次读取（A读两次，A不改变共享数据）</li>
</ul>
</li>
<li>幻像读(Phantom Read)：指一个事务对同一共享数据重复读取两次，但是发现第2次读取比第1次读取的结果中<strong>新增</strong>了一些数据。<ul>
<li>原因：多个事务并发执行，其中一个事务同时在对共享数据进行添加操作。</li>
<li>A读取，B插入，A再次读取（A读2次，A不改变共享数据）</li>
</ul>
</li>
<li>丢失更新(Lost Update)：一个事务对一共享数据进行<strong>更新处理</strong>，但是以后查询该共享数据值时，发现该数据与自己的更新值不一致。<ul>
<li>原因：多个事务并发执行，其中一个事务对共享数据进行了更新，并改变了前面的值。</li>
<li>A更新数据，B修改该数据，A再次读取（A读两次，A改变了共享数据）</li>
</ul>
</li>
</ul>
<h3 id="5-3-2-并发事务调度"><a href="#5-3-2-并发事务调度" class="headerlink" title="5.3.2 并发事务调度"></a>5.3.2 并发事务调度</h3><p>并发事务调度就是控制多个事务的数据操作语句<strong>按照恰当的顺序访问共享数据</strong>，使这些事务执行之后，避免造成数据的不一致性。</p>
<p><a href="https://imgtu.com/i/gNRmn0"><img src="https://z3.ax1x.com/2021/05/10/gNRmn0.png" srcset="/img/loading.gif" alt="gNRmn0.png"></a></p>
<p><em>并发控制调度器工作原理</em></p>
<p>DBMS并发控制调度器通过安排各事务数据读/写操作指令的<strong>执行顺序</strong>来实现。</p>
<p>在DBMS中，事务管理器将并发执行事务的SQL数据操作请求提交给并发控制调度器。由并发控制调度器将各个事务的SQL数据操作请求按照一定顺序进行调度执行，并完成对数据库缓冲区的读写操作。</p>
<p><strong>可串行化调度</strong>：在事务并发执行中，只有当<strong>事务中数据操作调度顺序的执行结果与事务串行执行结果一样时</strong>，该并发事务调度才能保证数据操作的正确性和一致性。符合这样效果的调度称为可串行化调度（<strong>确保数据库一致性的基本方法</strong>）。</p>
<p>DBMS并发事务调度目标：使并发事务调度实现的处理结果与串行化调度处理结果一致。</p>
<h3 id="5-3-3-数据库锁机制"><a href="#5-3-3-数据库锁机制" class="headerlink" title="5.3.3 数据库锁机制"></a>5.3.3 数据库锁机制</h3><p>为了解决多个事务并发对共享数据进行新增、更新、删除、查询带来的数据不一致性问题时，需要对共享数据进行加锁访问。</p>
<p>资源锁定：在每个事务更新、删除、新增共享数据时，禁止其他事务同时访问共享数据副本。</p>
<p><a href="https://imgtu.com/i/gNhh4O"><img src="https://z3.ax1x.com/2021/05/10/gNhh4O.png" srcset="/img/loading.gif" alt="gNhh4O.png"></a></p>
<p><em>基于锁表的数据库共享资源访问</em></p>
<p>在DBMS中，锁表机制与并发控制器结合，实现共享资源的锁定访问。</p>
<ul>
<li>加锁类型：<ul>
<li>排它锁定(Lock-X)——锁定后，封锁其他事务对共享数据的任何加锁操作，限制其他事务对共享数据的修改、删除、读取操作。</li>
<li>共享锁定(Lock-S)——锁定后，只封锁其他事务对加锁数据的修改或删除操作，但可以允许其他事务加锁数据进行共享数据读操作。</li>
</ul>
</li>
<li>共享资源锁定粒度：<ul>
<li>数据库——<strong>粒度最大</strong></li>
<li>表——粒度较大</li>
<li>页面——粒度中等</li>
<li>行——<strong>粒度小</strong></li>
<li>注意<ul>
<li>锁定粒度越大，DBMS管理越容易，但系统的并发数据处理能力就越差。</li>
<li>锁定粒度越小，DBMS管理就越复杂，但系统的并发数据处理能力就越强。</li>
</ul>
</li>
</ul>
</li>
<li>资源锁定实施方式<ul>
<li>隐式锁定——DBMS缺省执行</li>
<li>显式锁定——加锁命令显式执行</li>
</ul>
</li>
</ul>
<h3 id="5-3-4-基于锁机制的并发控制协议"><a href="#5-3-4-基于锁机制的并发控制协议" class="headerlink" title="5.3.4 基于锁机制的并发控制协议"></a>5.3.4 基于锁机制的并发控制协议</h3><p>为了实现并发事务对共享数据访问的串行化调度执行，还必须约束它们对共享数据的操作访问必须是以互斥方式进行。这就需要用到基于数据库锁机制的并发控制协议。</p>
<p><strong>锁操作的相容性表</strong></p>
<table>
<thead>
<tr>
<th><strong>类型</strong></th>
<th><strong>排他锁(LOCK-X)</strong></th>
<th><strong>共享锁(LOCK-S)</strong></th>
<th><strong>无锁</strong></th>
</tr>
</thead>
<tbody><tr>
<td><strong>排他锁(LOCK-X)</strong></td>
<td>否</td>
<td>否</td>
<td>是</td>
</tr>
<tr>
<td><strong>共享锁(LOCK-S)</strong></td>
<td>否</td>
<td><strong>是</strong></td>
<td>是</td>
</tr>
<tr>
<td><strong>无锁</strong></td>
<td>是</td>
<td>是</td>
<td>是</td>
</tr>
</tbody></table>
<p>不同规则的加锁协议，所能解决的数据库一致性问题是不一样的。</p>
<ul>
<li><p>加锁协议</p>
<ul>
<li><p>一级加锁协议：任何事务在修改共享数据对象之前，必须对该数据执行排它锁定指令，直到该事务处理完成，才进行解锁指令执行。</p>
<p>特点：使用一级加锁协议，<strong>可避免出现更新丢失问题</strong>。但不能解决“不可重复读取”、“脏读”等数据不一致问题。</p>
<ul>
<li><p>例：某航班剩余机票数据A的当前值为100张。现有分别来自不同售票点的两个并发事务T1和T2，其中T1事务将售出1张机票，T2事务将售出2张机票。以下分别给出它们在不加锁和按一级加锁协议的并发事务调度执行情况，见下图所示。</p>
<p><a href="https://imgtu.com/i/gaYNuj"><img src="https://z3.ax1x.com/2021/05/11/gaYNuj.png" srcset="/img/loading.gif" alt="gaYNuj.png"></a></p>
</li>
</ul>
</li>
<li><p>二级加锁协议：在一级加锁协议基础上，针对并发事务的共享数据读操作，必须对该数据执行共享锁定指令，读完数据后即刻释放共享锁定。</p>
<p>特点：该加锁协议<strong>可以防止“丢失更新”，脏读数据不一致问题</strong>。但有可能会出现“不可重复读取”的数据不一致问题。</p>
<ul>
<li><p>例：某航班剩余机票数据A的当前值为100张。现有分别来自不同售票点的两个并发事务T1和T2，其中T1事务将售出1张机票，T2事务进行机票空余数查询。以下分别给出它们在按一级加锁协议执行和按二级加锁协议的事务调度执行情况，见下图所示。</p>
<p><a href="https://imgtu.com/i/gaY456"><img src="https://z3.ax1x.com/2021/05/11/gaY456.png" srcset="/img/loading.gif" alt="gaY456.png"></a></p>
</li>
</ul>
</li>
<li><p>三级加锁协议：在一级加锁协议基础上，针对并发事务对共享数据进行读操作，必须对该数据执行共享锁定指令，直到该事务处理结束才释放共享锁定。</p>
<p>特点：该加锁协议不但可以防止“丢失更新”、“脏读”的数据不一致性问题，还可防止出现“不可重复读取”的数据一致性问题。</p>
<ul>
<li><p>例：某航班剩余机票数据A的当前值为100张。现有分别来自不同售票点的两个并发事务T1和T2，其中T1事务将售出1张机票，T2事务进行机票空余数查询。以下分别给出它们在按二级加锁协议执行和按三级加锁协议的并发事务调度执行情况，见下图所示。</p>
<p><a href="https://imgtu.com/i/gatdQe"><img src="https://z3.ax1x.com/2021/05/11/gatdQe.png" srcset="/img/loading.gif" alt="gatdQe.png"></a></p>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<table>
<thead>
<tr>
<th><strong>加锁协议级别</strong></th>
<th><strong>排它锁</strong></th>
<th><strong>共享锁</strong></th>
<th><strong>不</strong>丢失更新</th>
<th><strong>不脏读</strong></th>
<th>可重复读</th>
</tr>
</thead>
<tbody><tr>
<td><strong>一级</strong></td>
<td>全程加锁</td>
<td>不加</td>
<td>是</td>
<td>否</td>
<td>否</td>
</tr>
<tr>
<td><strong>二级</strong></td>
<td>全程加锁</td>
<td>开始时加锁，读完数据释放锁定</td>
<td>是</td>
<td>是</td>
<td>否</td>
</tr>
<tr>
<td><strong>三级</strong></td>
<td>全程加锁</td>
<td>全程加锁</td>
<td>是</td>
<td>是</td>
<td>是</td>
</tr>
</tbody></table>
<h3 id="5-3-5-两阶段锁定协议"><a href="#5-3-5-两阶段锁定协议" class="headerlink" title="5.3.5 两阶段锁定协议"></a>5.3.5 两阶段锁定协议</h3><p>一个给定的并发事务调度，当且仅当它是可串行化时，才能保证正确调度。</p>
<p><strong>保证可串行化的一个协议是：二阶段锁定协议</strong></p>
<ul>
<li>二阶段锁定协议：规定每个事务必须分两个阶段提出加锁和解锁申请<ul>
<li>增长阶段，事务只能获得锁，但不能释放锁。</li>
<li>缩减阶段，事务只能释放锁，但不能获得新锁。</li>
</ul>
</li>
</ul>
<p>若并发事务执行的所有事务都遵从两阶段锁定协议，则这些事务的任何并发调度都是可串行化调度，即这些并发调度执行结果可以保证数据库一致性。</p>
<h3 id="5-3-6-并发事务死锁解决"><a href="#5-3-6-并发事务死锁解决" class="headerlink" title="5.3.6 并发事务死锁解决"></a>5.3.6 并发事务死锁解决</h3><p>事务死锁状态：在基于锁机制的并发事务执行中，如果这些事务同时锁定两个以及以上资源时，可能会出现彼此都不能继续执行的状态。</p>
<ul>
<li>死锁出现的必要条件<ul>
<li>互斥条件</li>
<li>请求和保持条件</li>
<li>不剥夺条件</li>
<li>环路等待条件</li>
</ul>
</li>
<li>预防死锁的策略<ul>
<li>允许用户一次发出当前所需全部资源的锁定，使用完成后，再释放给其它用户访问。</li>
<li>规定所有应用程序锁定资源的顺序必须完全相同。</li>
</ul>
</li>
<li>解决死锁的办法<ul>
<li>当发生死锁时，回滚其中的一个事务，并取消它对数据库所做的改动。</li>
<li>并发事务执行时，一般采用超时法或事物等待图法检测是否存在死锁。</li>
<li>为降低解除死锁带来的开销，通常选择一个处理代价最小的事物进行撤销，释放该事务持有的所有锁定，使其他事物能够继续运行下去。</li>
</ul>
</li>
</ul>
<h3 id="5-3-7-事物隔离级别"><a href="#5-3-7-事物隔离级别" class="headerlink" title="5.3.7 事物隔离级别"></a>5.3.7 事物隔离级别</h3><p>不同的隔离级别可以避免不同的事物并发问题。</p>
<table>
<thead>
<tr>
<th>隔离级别</th>
<th>脏读</th>
<th>不可重复读</th>
<th>幻像读</th>
<th>丢失更新</th>
</tr>
</thead>
<tbody><tr>
<td>读取未提交</td>
<td>可能</td>
<td>可能</td>
<td>可能</td>
<td>可能</td>
</tr>
<tr>
<td>读取已提交</td>
<td>不可能</td>
<td>可能</td>
<td>可能</td>
<td>可能</td>
</tr>
<tr>
<td>可重复读</td>
<td>不可能</td>
<td>不可能</td>
<td>可能</td>
<td>可能</td>
</tr>
<tr>
<td>可串行化</td>
<td>不可能</td>
<td>不可能</td>
<td>不可能</td>
<td>不可能</td>
</tr>
</tbody></table>
<p>事务隔离级别设置是在DBMS中执行SET TRANSACTION命令来实现或通过管理工具设置。事务隔离级别设置越高，出现数据不一致的可能性越小，但系统吞吐量也越小。 </p>
<h2 id="5-4-安全管理——存取安全模型"><a href="#5-4-安全管理——存取安全模型" class="headerlink" title="5.4 安全管理——存取安全模型"></a>5.4 安全管理——存取安全模型</h2><h3 id="5-4-1-概述"><a href="#5-4-1-概述" class="headerlink" title="5.4.1 概述"></a>5.4.1 概述</h3><p>数据库系统安全(DataBase System Security)：为数据库系统采取安全保护措施，防止数据库系统及其数据遭到破坏、篡改和泄露。</p>
<p>数据库安全(DataBase Security)：采取各种安全措施对数据库及其相关文件进行保护，以确保数据库的数据安全。</p>
<p>数据库安全主要通过DBMS安全机制实现，如DBMS的用户标识与鉴别、存取控制、视图过滤，以及数据加密存储技术。</p>
<ul>
<li>典型数据库安全问题：<ul>
<li>黑客利用系统漏洞，攻击系统运行、窃取和篡改系统数据。</li>
<li>内部人员非法地泄露、篡改、删除系统的用户数据。</li>
<li>系统运维人员操作失误导致数据被删除或数据库服务器系统宕机</li>
<li>系统故障导致数据库的数据损坏、数据丢失、数据库实例无法启动。</li>
<li>意外灾害事件（火灾、水灾、地震等自然灾害）导致系统被破坏。</li>
</ul>
</li>
</ul>
<h3 id="5-4-2-数据库系统安全模型"><a href="#5-4-2-数据库系统安全模型" class="headerlink" title="5.4.2 数据库系统安全模型"></a>5.4.2 数据库系统安全模型</h3><p><a href="https://imgtu.com/i/gafgfO"><img src="https://z3.ax1x.com/2021/05/11/gafgfO.png" srcset="/img/loading.gif" alt="gafgfO.png"></a></p>
<ul>
<li>身份验证：从<strong>应用系统层面</strong>确认登录用户是否是合法使用者。</li>
<li>权限控制：从<strong>DBMS系统层面</strong>通过存取权限机制控制用户对数据的访问。</li>
<li>系统防护：从<strong>操作系统层面</strong>提供的安全机制防范非法系统访问。</li>
<li>加密存储：从<strong>数据存储层面</strong>通过加密算法对数据库中数据进行加密存储。</li>
<li>数据库系统安全模型中<strong>，最基本</strong>的安全管理技术手段：DBMS提供的用户授权与访问权限控制功能。该功能用来限制特定用户对特定对象进行授权的操作。o n</li>
</ul>
<p><a href="https://imgtu.com/i/gahaUP"><img src="https://z3.ax1x.com/2021/05/11/gahaUP.png" srcset="/img/loading.gif" alt="gahaUP.png"></a></p>
<p>在数据库存取控制安全模型中，每个数据库对象被定义若干操作访问权限。每个用户可以对应多个角色，每个角色可以对应多个用户。用户、角色均可以被赋予若干数据库对象的操作访问权限。一旦用户通过系统身份认证，DBMS就限制该用户在权限许可的范围内针对特定数据库对象进行访问操作。</p>
<p>例：工程项目管理系统中，假定系统用户有三类角色：员工、经理和系统管理员。它们对数据库各个表对象的拥有权限见下表所示。</p>
<table>
<thead>
<tr>
<th align="center">表</th>
<th align="center">员工</th>
<th align="center">经理</th>
<th align="center">系统管理员</th>
</tr>
</thead>
<tbody><tr>
<td align="center">Department（部门表）</td>
<td align="center">读取</td>
<td align="center">读取、插入、修改、删除</td>
<td align="center">赋予权限、修改结构</td>
</tr>
<tr>
<td align="center">Employee（员工表）</td>
<td align="center">读取、插入、修改</td>
<td align="center">读取、插入、修改、删除</td>
<td align="center">赋予权限、修改结构</td>
</tr>
<tr>
<td align="center">Project（项目表）</td>
<td align="center">读取</td>
<td align="center">取、插入、修改、删除</td>
<td align="center">赋予权限、修改结构</td>
</tr>
<tr>
<td align="center">Assign（任务表）</td>
<td align="center">读取</td>
<td align="center">读取、插入、修改、删除</td>
<td align="center">赋予权限、修改结构</td>
</tr>
</tbody></table>
<p><a href="https://imgtu.com/i/ga4feA"><img src="https://z3.ax1x.com/2021/05/11/ga4feA.png" srcset="/img/loading.gif" alt="ga4feA.png"></a></p>
<p>例：选课管理系统中，学生、教师和教务管理员角色的数据库表对象访问权限设计。</p>
<table>
<thead>
<tr>
<th>数据库表</th>
<th>学生</th>
<th>教师</th>
<th>教务管理人员</th>
</tr>
</thead>
<tbody><tr>
<td>College</td>
<td>查询</td>
<td>查询</td>
<td>查询、插入、修改、删除</td>
</tr>
<tr>
<td>Course</td>
<td>查询</td>
<td>查询</td>
<td>查询、插入、修改、删除</td>
</tr>
<tr>
<td>Teacher</td>
<td>查询</td>
<td>查询</td>
<td>查询、插入、修改、删除</td>
</tr>
<tr>
<td>Student</td>
<td>查询、修改</td>
<td>查询、修改</td>
<td>查询、插入、修改、删除</td>
</tr>
<tr>
<td>Plan</td>
<td>查询</td>
<td>查询</td>
<td>查询、插入、修改、删除</td>
</tr>
<tr>
<td>Register</td>
<td>查询</td>
<td>查询</td>
<td>查询、插入、修改、删除</td>
</tr>
</tbody></table>
<h3 id="5-4-3-用户管理"><a href="#5-4-3-用户管理" class="headerlink" title="5.4.3 用户管理"></a>5.4.3 用户管理</h3><p>用户要访问数据库，必须先在DBMS中创建其账号，并成为数据库的用户。此后，用户每次访问数据库，都需要在DBMS进行身份验证，只有合法用户才能进入系统，访问操作数据库对象。</p>
<p><strong>用户管理</strong>：在数据库安全管理中，DBMS需要对每个用户进行身份属性管理，如用户创建、用户修改、用户删除管理等。</p>
<ul>
<li>实现用户管理：<ul>
<li>GUI</li>
<li>SQL</li>
</ul>
</li>
</ul>
<h4 id="用户创建"><a href="#用户创建" class="headerlink" title="用户创建"></a>用户创建</h4><p>数据库中，只能通过特定权限的用户创建其他用户，如系统管理员用户或超级用户可以执行创建用户的SQL操作命令语句，创建其他用户。</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs SQL"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">USER</span>  <span class="hljs-operator">&lt;</span>用户账号名<span class="hljs-operator">&gt;</span> [ [<span class="hljs-keyword">WITH</span>]  option […]];<br></code></pre></td></tr></table></figure>

<p>option：</p>
<figure class="highlight pgsql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs pgsql"><span class="hljs-keyword">SUPERUSER</span> | <span class="hljs-keyword">NOSUPERUSER</span>:指定创建用户是否为超级用户。<br><span class="hljs-keyword">CREATEDB</span> | <span class="hljs-keyword">NOSUPERUSER</span>:指定创建的用户是否具有创建数据库的权限。<br><span class="hljs-keyword">CREATEROLE</span> | <span class="hljs-keyword">NOCREATEROLE</span>:指定创建的用户是否具有创建角色的权限。<br><span class="hljs-keyword">INHERIT</span> | <span class="hljs-keyword">NOINHERIT</span>:指定创建的用户是否由继承角色的权限。<br><span class="hljs-keyword">LOGIN</span> | <span class="hljs-keyword">NOLOGIN</span>:指定创建的用户是否有登录权限。<br><span class="hljs-keyword">REPLICATION</span> | <span class="hljs-keyword">REPLICATION</span>:指定创建的用户是否具有复制权限。<br><span class="hljs-keyword">BYPASSRLS</span> | <span class="hljs-keyword">NOBYPASSRLS</span>:指定创建的用户是否具有绕过安全策略的权限。<br><span class="hljs-keyword">CONNECTION</span> <span class="hljs-keyword">LIMIT</span> connlimit:指定创建的用户访问数据库连接的数目限制。<br>[<span class="hljs-keyword">ENCRYPTED</span> | NOENCRYPTED] <span class="hljs-keyword">PASSWORD</span> <span class="hljs-string">&#x27;password&#x27;</span>:指定创建的用户密码是否需要加密。<br><span class="hljs-keyword">VALID</span> <span class="hljs-keyword">UNTIL</span> <span class="hljs-string">&#x27;timestamp&#x27;</span>:指定创建的用户密码失效时间。<br><span class="hljs-keyword">IN</span> <span class="hljs-keyword">ROLE</span> role_name [,……]:指定创建的用户成为哪些角色的成员。<br></code></pre></td></tr></table></figure>

<p>在pgAdmin 4 管理工具中，数据库”角色“与”用户“对象创建界面相同。区分”用户“与”角色“创建主要根据SQL语句的关键词是”CREATE USER”还是”CREATE ROLE”。此外，在“用户”创建中，默认拥有登录权限(Login)，而在“角色”创建中，默认不具有登录权限。</p>
<h4 id="用户修改"><a href="#用户修改" class="headerlink" title="用户修改"></a>用户修改</h4><p>对已有用户进行属性修改。</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs SQL"><span class="hljs-keyword">ALTER</span> <span class="hljs-keyword">USER</span>  <span class="hljs-operator">&lt;</span>用户名<span class="hljs-operator">&gt;</span>  [ [ <span class="hljs-keyword">WITH</span> ] option [ ... ] ];  	<span class="hljs-comment">--修改用户的属性</span><br><span class="hljs-keyword">ALTER</span> <span class="hljs-keyword">USER</span>  <span class="hljs-operator">&lt;</span>用户名<span class="hljs-operator">&gt;</span>  RENAME <span class="hljs-keyword">TO</span> <span class="hljs-operator">&lt;</span>新用户名<span class="hljs-operator">&gt;</span>;  		<span class="hljs-comment">--修改用户的名称</span><br>ALTER USER  &lt;用户名&gt;  SET &lt;参数项&gt; &#123; TO | = &#125; &#123; value | DEFAULT &#125;;<br>									<span class="hljs-comment">--修改用户的参数值  </span><br><span class="hljs-keyword">ALTER</span> <span class="hljs-keyword">USER</span>  <span class="hljs-operator">&lt;</span>用户名<span class="hljs-operator">&gt;</span>  RESET <span class="hljs-operator">&lt;</span>参数项<span class="hljs-operator">&gt;</span>;			<span class="hljs-comment">--重置用户参数值</span><br></code></pre></td></tr></table></figure>

<h4 id="用户删除"><a href="#用户删除" class="headerlink" title="用户删除"></a>用户删除</h4><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs SQL"><span class="hljs-keyword">DROP</span>  <span class="hljs-keyword">USER</span>  <span class="hljs-operator">&lt;</span>用户名<span class="hljs-operator">&gt;</span>; <br></code></pre></td></tr></table></figure>

<h3 id="5-4-4-权限管理"><a href="#5-4-4-权限管理" class="headerlink" title="5.4.4 权限管理"></a>5.4.4 权限管理</h3><h4 id="权限类型"><a href="#权限类型" class="headerlink" title="权限类型"></a>权限类型</h4><ul>
<li><p>权限类别</p>
<ul>
<li><p>数据库系统权限</p>
</li>
<li><p>数据库对象访问操作权限</p>
<p>如对数据库表的查询、添加、更新、删除、修改</p>
</li>
<li><p>数据库对象定义操作权限</p>
<p>如对数据库表、视图、存储过程、用户自定义函数、索引等对象的创建、删除、修改</p>
</li>
</ul>
</li>
<li><p>系统管理员(超级用户)具有最高的权限，可以对其他用户或角色进行权限分配和管理。数据库对象拥有者(DBO)对其拥有的对象具有全部权限。</p>
</li>
</ul>
<h4 id="权限管理"><a href="#权限管理" class="headerlink" title="权限管理"></a>权限管理</h4><p>数据库权限管理：指DBA管理员或数据库对象拥有者对其所拥有对象进行权限控制设置。</p>
<ul>
<li><p>权限管理基本操作：</p>
<ul>
<li><p>授予权限</p>
</li>
<li><p>收回权限</p>
</li>
<li><p>拒绝权限</p>
</li>
</ul>
</li>
<li><p>执行SQL控制语句进行权限管理</p>
<p>GRANT授权</p>
<p>REVOKE收回权限</p>
<p>DENY拒绝权限</p>
</li>
</ul>
<figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs sql">GRANT  &lt;权限名&gt; ON  &lt;对象名&gt;  TO &#123;数据库用户名|用户角色名&#125;；<br>REVOKE  &lt;权限名&gt; ON  &lt;对象名&gt;  FROM &#123;数据库用户名|用户角色名&#125;；<br>DENY  &lt;权限名&gt; ON  &lt;对象名&gt; TO &#123;数据库用户名|用户角色名&#125;；<br></code></pre></td></tr></table></figure>

<h3 id="5-4-5-角色管理"><a href="#5-4-5-角色管理" class="headerlink" title="5.4.5 角色管理"></a>5.4.5 角色管理</h3><p>在DBMS中，为了方便对众多用户及其权限进行管理，通常将一组具有相同权限的用户定义为角色(Role)。</p>
<p>进行角色管理的好处：DBA系统管理人员只需要对具有不同权限的用户分类进行划分，并将其定义为不同的角色，不同的角色授予不同的权限，而不必关心具体有多少用户。当角色成员发生变化时，DBA无须做任何关于权限的操作。</p>
<p>DBMS角色分类：</p>
<ul>
<li>预定义系统角色：系统角色是数据库系统内建的角色，它们在数据库系统中已经被定义好相应的操作权限。</li>
<li>用户自定义角色：DBA根据业务应用需要，设计了不同权限范围的用户类别。</li>
</ul>
<p>用户自定义角色管理，包括：</p>
<ul>
<li>角色创建</li>
<li>角色修改</li>
<li>角色删除</li>
</ul>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs sql"><span class="hljs-keyword">CREATE</span>  ROLE  <span class="hljs-operator">&lt;</span>角色名<span class="hljs-operator">&gt;</span> [ [ <span class="hljs-keyword">WITH</span> ] option [ ... ] ]; 	 <span class="hljs-comment">--创建角色</span><br><span class="hljs-keyword">ALTER</span>  ROLE  <span class="hljs-operator">&lt;</span>角色名<span class="hljs-operator">&gt;</span>  [ [ <span class="hljs-keyword">WITH</span> ] option [ ... ] ]; 	 <span class="hljs-comment">--修改角色属性</span><br><span class="hljs-keyword">ALTER</span>  ROLE  <span class="hljs-operator">&lt;</span>角色名<span class="hljs-operator">&gt;</span>  RENAME <span class="hljs-keyword">TO</span> <span class="hljs-operator">&lt;</span>新角色名<span class="hljs-operator">&gt;</span>; 		 <span class="hljs-comment">--修改角色名称 </span><br>ALTER  ROLE  &lt;角色名&gt;  SET &lt;参数项&gt; &#123; TO | = &#125; &#123; value | DEFAULT &#125;; <br>									 <span class="hljs-comment">--修改角色参数值</span><br><span class="hljs-keyword">ALTER</span>  ROLE  <span class="hljs-operator">&lt;</span>角色名<span class="hljs-operator">&gt;</span>  RESET <span class="hljs-operator">&lt;</span>参数项<span class="hljs-operator">&gt;</span>;			 <span class="hljs-comment">--复位角色参数值</span><br><span class="hljs-keyword">DROP</span>  ROLE  <span class="hljs-operator">&lt;</span>角色名<span class="hljs-operator">&gt;</span>;						 <span class="hljs-comment">--删除指定角色</span><br></code></pre></td></tr></table></figure>

<p>option——角色属性</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs sql">SUPERUSER <span class="hljs-operator">|</span> NOSUPERUSER:指定创建用户是否为超级用户。<br>CREATEDB <span class="hljs-operator">|</span> NOSUPERUSER:指定创建的用户是否具有创建数据库的权限。<br>CREATEROLE <span class="hljs-operator">|</span> NOCREATEROLE:指定创建的用户是否具有创建角色的权限。<br>INHERIT <span class="hljs-operator">|</span> NOINHERIT:指定创建的用户是否由继承角色的权限。<br>LOGIN <span class="hljs-operator">|</span> NOLOGIN:指定创建的用户是否有登录权限。<br>REPLICATION <span class="hljs-operator">|</span> REPLICATION:指定创建的用户是否具有复制权限。<br>BYPASSRLS <span class="hljs-operator">|</span> NOBYPASSRLS:指定创建的用户是否具有绕过安全策略的权限。<br>CONNECTION LIMIT connlimit:指定创建的用户访问数据库连接的数目限制。<br>[ENCRYPTED <span class="hljs-operator">|</span> NOENCRYPTED] PASSWORD <span class="hljs-string">&#x27;password&#x27;</span>:指定创建的用户密码是否需要加密。<br>VALID UNTIL <span class="hljs-string">&#x27;timestamp&#x27;</span>:指定创建的用户密码失效时间。<br><span class="hljs-keyword">IN</span> ROLE role_name [,……]:指定创建的用户成为哪些角色的成员。<br><span class="hljs-keyword">IN</span> ROLE role_name[,……]:指定创建的角色称为哪些角色的成员。<br>ROLE role_name[,……]:指定创建的角色成为哪些角色的组角色。<br><span class="hljs-keyword">USER</span> role_name[,……]:指定创建的角色成为哪些用户的角色。<br></code></pre></td></tr></table></figure>

<h2 id="5-5-数据库备份与恢复"><a href="#5-5-数据库备份与恢复" class="headerlink" title="5.5 数据库备份与恢复"></a>5.5 数据库备份与恢复</h2><p>数据库备份：是指将数据库当前<strong>数据和状态</strong>进行副本复制，以便当数据库受到破坏或丢失数据时可以进行修复。</p>
<p>数据库恢复：是指数据库中数据丢失或被破坏时，从备份副本将数据库从错误状态<strong>恢复到某一正确状态</strong>。</p>
<h3 id="5-5-1-数据库备份"><a href="#5-5-1-数据库备份" class="headerlink" title="5.5.1 数据库备份"></a>5.5.1 数据库备份</h3><h4 id="备份内容"><a href="#备份内容" class="headerlink" title="备份内容"></a>备份内容</h4><p>在数据库系统中，除了<strong>用户数据库</strong>外，还有保存数据库结构和系统参数的<strong>系统数据库</strong>。</p>
<p>备份内容：包括数据文件、日志文件等。</p>
<p>备份角色：可以是服务器管理员（Sysadmin）、数据库所有者（DBO）、数据库备份员（DB Backupoperator）角色之一。</p>
<h4 id="备份方式"><a href="#备份方式" class="headerlink" title="备份方式"></a>备份方式</h4><p>典型备份方式</p>
<ul>
<li><p>完全数据库备份</p>
<p>备份数据库所有内容的方式，可以备份整个数据库，包含用户表、系统表、索引、视图、存储过程等所有数据库对象。</p>
</li>
<li><p>差异数据库备份</p>
<p>只备份上次数据库备份以来的发生变化的数据，它比完整数据库备份耗费的存储空间少，而且可以快速完成数据备份。适合数据变化频繁的数据库系统。</p>
</li>
<li><p>事务日志备份</p>
<p>只备份自上一次日志文件备份以来的事务日志数据。事务日志备份所需的时间和空间比差异数据库备份更少，而且支持事务的回滚操作。使用事务日志备份文件可以将数据库恢复到故障点时刻的状态，相比差异数据库备份，可进一步减少数据丢失风险，适合数据变化频繁的数据库系统。</p>
</li>
<li><p>文件备份</p>
<p>数据库通常由存储在磁盘上的若干数据文件构成。可以直接通过复制数据文件方式实现数据库备份。这种文件备份方式与事务日志备份方式结合才有实际意义。</p>
</li>
</ul>
<p>按照数据库备份时刻<strong>是否需要停止实例运行</strong>：</p>
<ul>
<li><p>冷备份</p>
<p>当数据库处于关闭状态时，进行的数据库备份被称为冷备份。这种备份方式可以很好的保证数据库完整性备份，不会出现丢失数据的情况，但数据库实例必须停止运行。因此，基于数据库的业务系统会被暂时终止运行。</p>
</li>
<li><p>热备份</p>
<p>在数据库实例处于运行状态下，进行的数据库备份被称为热备份。这种备份方式能较好地实现实时数据备份，但会对数据库服务器、备份服务器及网络系统带来处理的复杂性，并且影响生产系统的性能。</p>
</li>
</ul>
<h4 id="备份设备"><a href="#备份设备" class="headerlink" title="备份设备"></a>备份设备</h4><p>备份设备：实现数据库备份的存储设备。比如<strong>磁盘阵列、磁带库、光盘库</strong>。</p>
<p>备份时机：当系统数据库重要数据被修改、日志被清理、用户数据库创建、用户数据库加载等事件出现时。</p>
<h3 id="5-5-2-PostgreSQL数据库备份方法"><a href="#5-5-2-PostgreSQL数据库备份方法" class="headerlink" title="5.5.2 PostgreSQL数据库备份方法"></a>5.5.2 PostgreSQL数据库备份方法</h3><h4 id="使用实用程序工具进行数据库备份"><a href="#使用实用程序工具进行数据库备份" class="headerlink" title="使用实用程序工具进行数据库备份"></a>使用实用程序工具进行数据库备份</h4><ul>
<li><p>pg_dump：可用于选定数据库对象的数据备份，如既可以选定某数据库进行数据备份，也可以选定某数据库中的指定schema或者选择的某数据库进行数据备份。</p>
<p>pg_dump实用程序工具在<strong>操作系统</strong>下运行，并需要指定选项参数</p>
<p>运行的命令格式：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">pg_dump [连接选项] [一般选项] [输出控制选项]数据库名称<br></code></pre></td></tr></table></figure>

<ul>
<li><p>备份数据库</p>
<figure class="highlight pgsql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs pgsql">pg_dump -h localhost -p <span class="hljs-number">5432</span> -U postgre -f g:\ProjectDB.<span class="hljs-keyword">sql</span> 	ProjectDB<br></code></pre></td></tr></table></figure>
</li>
<li><p>备份public模式下的对象文件</p>
<figure class="highlight pgsql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs pgsql">pg_dump -h localhost -p <span class="hljs-number">5432</span> -U postgre -n <span class="hljs-built_in">public</span> -f g:\ProjectDB.<span class="hljs-keyword">sql</span> 	ProjectDB<br></code></pre></td></tr></table></figure>

</li>
</ul>
<p>默认备份为纯文本。</p>
</li>
<li><p>pg_dumpall：用于全库数据备份，即将当前postgreSQL服务实例中的所有数据库进行数据备份，同时也将数据库中的表空间和角色备份到数据文件中。</p>
<p>pg_dumpall实用程序工具在<strong>操作系统</strong>下运行，并需要指定选项参数。</p>
<p>运行的命令格式：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">pg_dumpall [连接选项] [一般选项] [输出控制选项]数据库名称<br></code></pre></td></tr></table></figure>

<ul>
<li><p>备份全数据库</p>
<figure class="highlight pgsql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs pgsql">pg_dumpall -h localhost -p <span class="hljs-number">5432</span> -U postgre -f g:\ProjectDB.<span class="hljs-keyword">sql</span><br></code></pre></td></tr></table></figure>

</li>
</ul>
</li>
</ul>
<h4 id="GUI备份（略）"><a href="#GUI备份（略）" class="headerlink" title="GUI备份（略）"></a>GUI备份（略）</h4><h3 id="5-5-3-数据库恢复"><a href="#5-5-3-数据库恢复" class="headerlink" title="5.5.3 数据库恢复"></a>5.5.3 数据库恢复</h3><h4 id="恢复时机"><a href="#恢复时机" class="headerlink" title="恢复时机"></a>恢复时机</h4><ul>
<li><p>事务故障</p>
</li>
<li><p>数据库服务器硬件故障</p>
</li>
<li><p>存储介质损坏 </p>
</li>
<li><p>系统断电</p>
</li>
<li><p>系统崩溃</p>
</li>
<li><p>人为误操作</p>
</li>
</ul>
<p>这些意外事件会使数据库处于不正确状态，需要采取相应的恢复策略对数据库进行恢复处理。</p>
<ul>
<li><p>事务故障的数据恢复</p>
<p>事务故障：事务在运行中由于出现意外事件（如计算溢出、事务死锁等）而非正常终止。</p>
<p>事务故障可能会导致数据库出现数据不一致、数据丢失等问题，需要对事务进行<strong>回滚</strong>操作处理，使数据库<strong>恢复到没有运行该事务前的正确数据状态</strong>。该数据恢复<strong>由DBMS自动完成</strong>。</p>
</li>
<li><p>系统崩溃的数据恢复</p>
<p>数据崩溃：数据库服务器在运行中由于出现意外事件（如突然断电、操作系统故障、硬件故障等）而非正常终止。</p>
<p>系统崩溃可能会导致数据库出现数据不一致、数据丢失等问题，需要数据库系统日志文件在<strong>系统重启</strong>过程中，对数据库进行恢复操作处理，使数据库<strong>恢复到系统崩溃前的状态</strong>。该数据恢复<strong>由DBMS自动完成</strong>。</p>
</li>
<li><p>存储介质损坏的数据恢复</p>
<p>存储介质损坏：数据库系统所在的存储介质意外损坏，导致数据库损坏或数据丢失。</p>
<p>当这类事件出现时，只能通过在<strong>新介质上重建</strong>数据库系统，并将最近一次数据库完整备份文件版本进行基本数据恢复，然后<strong>使用该版本之后的数据库差异备份版本和事务日志备份文件逐一进行数据库恢复处理，直到使数据库系统恢复到介质损坏前的状态</strong>。该处理<strong>需要系统管理员使用专门恢复工具和备份文件来完成</strong>。</p>
</li>
</ul>
<h4 id="恢复技术"><a href="#恢复技术" class="headerlink" title="恢复技术"></a>恢复技术</h4><p>以上数据库恢复处理策略都需要应用数据库恢复技术实现。</p>
<p>数据库恢复技术：利用<strong>数据库备份文件和数据库事务日志文件</strong>来实现数据库恢复处理。</p>
<p>应根据用户恢复要求，采用前滚事务方式或回滚事务方式恢复数据库。</p>
<p>通过备份文件进行恢复的特点：</p>
<ul>
<li>恢复技术简单，易于实现。</li>
<li>对于多用户系统，<strong>难以接受备份周期内出现的数据丢失</strong>。</li>
</ul>
<p><a href="https://imgtu.com/i/gdVmqg"><img src="https://z3.ax1x.com/2021/05/11/gdVmqg.png" srcset="/img/loading.gif" alt="gdVmqg.png"></a></p>
<h4 id="前滚事务方式"><a href="#前滚事务方式" class="headerlink" title="前滚事务方式"></a>前滚事务方式</h4><p>用户希望使用<strong>故障前的数据库备份文件</strong>进行恢复处理，可采用前滚事务恢复方式将数据库恢复到故障发生前一时刻的数据库状态。这是在<strong>数据库备份版本</strong>基础上，通过系统执行事务日志文件中记录的操作命令来实现数据库恢复处理，即将数据库记录的后像数据重新应用到数据库中，从而将数据库恢复到发生故障前一时刻的状态。</p>
<p><strong>后像数据：数据库备份时刻到故障时刻期间所记录的事务修改数据。</strong></p>
<h4 id="回滚事务方式"><a href="#回滚事务方式" class="headerlink" title="回滚事务方式"></a>回滚事务方式</h4><p>用户希望使用故障后的数据库进行恢复处理时，可采用回滚事务恢复方式将数据库恢复到故障发生前一时刻的数据库状态。这是在<strong>故障后的数据库</strong>的基础上，通过系统回滚事务操作来实现的。在恢复处理时，取消错误执行或部分完成的事务对数据库的修改，将系统记录的前像数据恢复到数据库中，从而将数据库恢复到发生故障前一时刻的状态。</p>
<p><strong>前像数据：数据库故障时刻之前所记录的事务修改数据。</strong></p>
<h3 id="5-5-4-PostgreSQL数据库恢复办法"><a href="#5-5-4-PostgreSQL数据库恢复办法" class="headerlink" title="5.5.4 PostgreSQL数据库恢复办法"></a>5.5.4 PostgreSQL数据库恢复办法</h3><h4 id="使用psql实用工具恢复SQL文本格式的数据备份"><a href="#使用psql实用工具恢复SQL文本格式的数据备份" class="headerlink" title="使用psql实用工具恢复SQL文本格式的数据备份"></a>使用psql实用工具恢复SQL文本格式的数据备份</h4><p>psql实用程序工具在<strong>操作系统</strong>下运行，并需要指定选项参数，基本语法：</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs sql">psql [连接选项] <span class="hljs-operator">-</span>d 恢复的数据库 <span class="hljs-operator">-</span>f 备份文件<br></code></pre></td></tr></table></figure>

<p>实例</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs sql">psql <span class="hljs-operator">-</span>h localhost <span class="hljs-operator">-</span>p <span class="hljs-number">5432</span> <span class="hljs-operator">-</span>U postgres <span class="hljs-operator">-</span>d ProjectDB <span class="hljs-operator">-</span>f g:\ProjectDB.sql<br></code></pre></td></tr></table></figure>

<h4 id="使用pg-restore实用程序工具恢复其他格式的数据备份"><a href="#使用pg-restore实用程序工具恢复其他格式的数据备份" class="headerlink" title="使用pg_restore实用程序工具恢复其他格式的数据备份"></a>使用pg_restore实用程序工具恢复其他格式的数据备份</h4><p>使用pg_restore程序工具来恢复pg_dump工具创建的自定义压缩格式、TAR包格式或目录格式的数据备份文件。</p>
<p>pg_restore实用程序工具在<strong>操作系统</strong>下运行，并需要指定选项参数，基本语法：</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs sql">pg_restore [连接选项][一般选项] [恢复控制选项] <span class="hljs-operator">-</span>f 备份文件<br></code></pre></td></tr></table></figure>

<p>例：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs psql">pg_restore -h localhost -p 5432 -U postgres -d ProjectDB -c g:\ProjectDB.bak<br></code></pre></td></tr></table></figure>

<h1 id="第六章-数据库应用编程"><a href="#第六章-数据库应用编程" class="headerlink" title="第六章 数据库应用编程"></a><strong>第六章 数据库应用编程</strong></h1><p>数据库应用编程主要包括：数据库的连接与访问技术、嵌入式SQL编程技术、存储过程编程技术、触发器编程技术以及游标技术。</p>
<p><a href="https://imgtu.com/i/g0oiN9"><img src="https://z3.ax1x.com/2021/05/13/g0oiN9.png" srcset="/img/loading.gif" alt="g0oiN9.png"></a></p>
<ul>
<li>编程简介<ul>
<li>客户端应用程序编程</li>
<li>数据库服务器端编程</li>
<li>编程结合ODBC/JDBC</li>
</ul>
</li>
</ul>
<h2 id="6-1-数据库连接技术"><a href="#6-1-数据库连接技术" class="headerlink" title="6.1 数据库连接技术"></a>6.1 数据库连接技术</h2><p>各种高级语言都采用了各自不同的数据库访问接口，并通过这些接口，执行SQL语句，进行数据库管理。</p>
<ul>
<li>数据库接口中间件：<ul>
<li>ODBC(Open DataBase Connectivity，开放数据库连接)，微软</li>
<li>JDBC(Java DataBase Connectivity，Java开放数据库连接)</li>
<li>ADO.NET，微软</li>
<li>PDO(PHP Data Object，PHP数据对象)</li>
</ul>
</li>
</ul>
<h3 id="6-1-1-ODBC技术"><a href="#6-1-1-ODBC技术" class="headerlink" title="6.1.1 ODBC技术"></a>6.1.1 ODBC技术</h3><ul>
<li><p>ODBC技术背景：</p>
<ul>
<li>在传统应用开发，应用系统通常选用特定的DBMS管理系统；</li>
<li>网络环境下，应用系统通常需要对多种数据库的实现互连和资源共享；</li>
<li>如果从一种DBMS改变到另一种DBMS，就意味着要重写应用程序；</li>
<li>而在同一应用系统中，编制多种能在不同的DBMS上运行的应用程序，显然不是可取的方法。</li>
</ul>
</li>
<li><p>Microsoft推出了开放式数据库互连（Open DataBase Connectivity，简写为ODBC）技术。</p>
</li>
<li><p>ODBC实现了应用程序对多种不同DBMS的数据库的访问，实现了数据库连接方式的变革。 </p>
</li>
<li><p>OBDC简介</p>
<ul>
<li>ODBC定义了一套基于SQL的、公共的、与数据库无关的API（应用程序设计接口）；</li>
<li>使每个应用程序利用相同的源代码就可访问不同的数据库系统，存取多个数据库中的数据；</li>
<li>从而使得应用程序与数据库管理系统（DBMS）之间在逻辑上的独立性，使应用程序具有数据库无关性。</li>
</ul>
</li>
</ul>
<h4 id="ODBC层次结构"><a href="#ODBC层次结构" class="headerlink" title="ODBC层次结构"></a>ODBC层次结构</h4><p><a href="https://imgtu.com/i/g0H5Cj"><img src="https://z3.ax1x.com/2021/05/13/g0H5Cj.png" srcset="/img/loading.gif" alt="g0H5Cj.png"></a></p>
<p><a href="https://imgtu.com/i/g0HWVS"><img src="https://z3.ax1x.com/2021/05/13/g0HWVS.png" srcset="/img/loading.gif" alt="g0HWVS.png"></a></p>
<p><a href="https://imgtu.com/i/g0HfUg"><img src="https://z3.ax1x.com/2021/05/13/g0HfUg.png" srcset="/img/loading.gif" alt="g0HfUg.png"></a></p>
<p><a href="https://imgtu.com/i/g0HI8s"><img src="https://z3.ax1x.com/2021/05/13/g0HI8s.png" srcset="/img/loading.gif" alt="g0HI8s.png"></a></p>
<p><a href="https://imgtu.com/i/g0Hh5Q"><img src="https://z3.ax1x.com/2021/05/13/g0Hh5Q.png" srcset="/img/loading.gif" alt="g0Hh5Q.png"></a></p>
<p><a href="https://imgtu.com/i/g0Ho2n"><img src="https://z3.ax1x.com/2021/05/13/g0Ho2n.png" srcset="/img/loading.gif" alt="g0Ho2n.png"></a></p>
<p><a href="https://imgtu.com/i/g0HTvq"><img src="https://z3.ax1x.com/2021/05/13/g0HTvq.png" srcset="/img/loading.gif" alt="g0HTvq.png"></a></p>
<h4 id="应用程序使用ODBC访问数据库的步骤"><a href="#应用程序使用ODBC访问数据库的步骤" class="headerlink" title="应用程序使用ODBC访问数据库的步骤"></a>应用程序使用ODBC访问数据库的步骤</h4><p>①首先必须用ODBC管理器注册一个数据源；</p>
<p>②管理器根据数据源提供的数据库位置、数据库类型及ODBC驱动程序等信息，建立起ODBC与具体数据库的联系；</p>
<p>③应用程序只需将数据源名提供给ODBC，ODBC就能建立起与相应数据库的连接；</p>
<p>④这样，应用程序就可以通过驱动程序管理器与数据库交换信息；</p>
<p>⑤驱动程序管理器负责将应用程序对ODBC API的调用传递给正确的驱动程序；</p>
<p>⑥驱动程序在执行完相应的SQL操作后，将结果通过驱动程序管理器返回给应用程序。</p>
<h3 id="6-1-2-JDBC技术"><a href="#6-1-2-JDBC技术" class="headerlink" title="6.1.2 JDBC技术"></a>6.1.2 JDBC技术</h3><p>JDBC，是一种用于执行SQL语句的Java API。</p>
<p>它由一组用Java编程语言编写的类和接口组成。这个API由java.sql.*包中的一些类和接口组成，它为数据库开发人员提供了一个标准的API，使他们能够用纯Java API 来编写数据库应用程序。</p>
<p>注意：使用JDBC访问数据库需要相应数据库的JDBC驱动程序。</p>
<p><strong>JDBC工作原理</strong></p>
<p><a href="https://imgtu.com/i/g0XJ00"><img src="https://z3.ax1x.com/2021/05/13/g0XJ00.png" srcset="/img/loading.gif" alt="g0XJ00.png"></a></p>
<p><strong>JDBC访问数据库步骤</strong></p>
<p><a href="https://imgtu.com/i/g0Xh1H"><img src="https://z3.ax1x.com/2021/05/13/g0Xh1H.png" srcset="/img/loading.gif" alt="g0Xh1H.png"></a></p>
<ul>
<li><p>驱动程序分类</p>
<p>按标准分：</p>
<ul>
<li>面向应用程序的API接口</li>
<li>面向驱动程序的API接口</li>
</ul>
<p>按操作方式分：</p>
<ul>
<li>JDBC-ODBC Bridge Driver</li>
<li>Native-API partly-Java Driver</li>
<li>JDBC-Net All-Java Driver</li>
<li>Native-protocol All-Java Driver</li>
</ul>
</li>
<li><p>JDBC核心类和接口</p>
<ul>
<li><p>java.sql.DriverManager</p>
<p>JDBC管理类，处理加载和跟踪驱动程序，建立数据库和相应驱动程序之间的连接。</p>
</li>
<li><p>java.sql.Connection</p>
<p>提供的Connection对象代表与数据库的连接。连接过程包括所执行的SQL语句和该连接上所返回的结果。一个应用程序可与单个数据库有一个或多个连接，或者可与多个数据库建立连接。</p>
</li>
<li><p>java.sql.Statement</p>
</li>
<li><p>java.PreparedStatement</p>
</li>
<li><p>java.sql.CallableStatement</p>
</li>
<li><p>java.sql.ResultSet</p>
</li>
</ul>
</li>
</ul>
<h2 id="6-3-存储过程"><a href="#6-3-存储过程" class="headerlink" title="6.3 存储过程"></a>6.3 存储过程</h2><ul>
<li><p>存储过程（Stored Procedure）是一种数据库的对象；</p>
</li>
<li><p>由一组能完成特定功能的SQL 语句集构成；</p>
</li>
<li><p>是把经常会被重复使用的SQL语句逻辑块封装起来，经编译后，存储在数据库服务器端；</p>
</li>
<li><p>当被再次调用时，而不需要再次编译；</p>
</li>
<li><p>当客户端连接到数据库时，用户通过指定存储过程的名字并给出参数，数据库就可以找到相应的存储过程予以调用。</p>
</li>
</ul>
<h3 id="6-3-1-存储过程基础知识"><a href="#6-3-1-存储过程基础知识" class="headerlink" title="6.3.1 存储过程基础知识"></a>6.3.1 存储过程基础知识</h3><ul>
<li><p>不同的数据库系统创建存储过程的语法存在差异；</p>
</li>
<li><p>许多数据库为创建存储过程和函数提供不同命令；</p>
</li>
<li><p>如ORACLE、MySQL、SQL SERVER等数据库，使用CREATE PRECEDURE命令创建存储过程，使用CREATE FUNCTION命令创建函数。</p>
</li>
<li><p>PostgreSQL使用CREATE FUNCTION命令创建存储过程。(11版本后可以用CREATE PRECEDURE)</p>
</li>
</ul>
<h4 id="创建存储过程"><a href="#创建存储过程" class="headerlink" title="创建存储过程"></a>创建存储过程</h4><p>PostgreSQL内置过程控制语言PL/pgSQL中，创建存储过程语法：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs plsql">CREATE [ OR REPLACE ] FUNCTION&#x2F;PROCEDURE  name<br>    ( [ [ argmode ] [ argname ] argtype [ &#123; DEFAULT | &#x3D; &#125; default_expr ] [, ...] ] )<br>    [ RETURNS retype | RETURNS TABLE ( column_name  column_type [, ...] ) ]<br>AS $$         &#x2F;&#x2F;$$用于声明存储过程的实际代码的开始<br>DECLARE<br>        -- 声明段<br>BEGIN<br>        --函数体语句<br>END;<br>$$ LANGUAGE lang_name;  &#x2F;&#x2F;$$ 表明代码的结束, LANGUAGE后面指明所用的编程语言<br></code></pre></td></tr></table></figure>

<ul>
<li>关键字解释：<ul>
<li>name：要创建的存储过程名；</li>
<li>OR REPLACE ：覆盖同名的存储过程；</li>
<li>argmode：存储过程参数的模式可以为IN、OUT或INOUT，默认/缺省值是IN。</li>
<li>argname：形式参数的名字。</li>
<li>argtype：返回值的数据类型。</li>
<li>retype：指示RETURNS返回值的数据类型。</li>
<li>RETURNS：返回值；RETURNS TABLE：返回二维表</li>
<li>AS $$：用于声明存储过程的实际代码的开始，当编辑器扫描到下一个$$时，表明代码结束。</li>
<li>DECLARE：PL/pgSQL指示声明存出过程的局部变量。</li>
<li>BEGIN……END：用来定义存储过程的执行体语句。</li>
<li>LANGUAGE：在后面的lang_name指明存储过程是使用PL/pgSQL实现的。</li>
</ul>
</li>
</ul>
<h4 id="声明局部变量"><a href="#声明局部变量" class="headerlink" title="声明局部变量"></a>声明局部变量</h4><ul>
<li><p>注释：</p>
<ul>
<li><pre><code>--单行注释
<figure class="highlight autohotkey"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs autohotkey"><br>* ```<br>  <span class="hljs-comment">/*多行注释*/</span><br></code></pre></td></tr></table></figure>
</code></pre>
</li>
</ul>
</li>
</ul>
<p>在块中使用的变量大都必须在声明段中进行声明，但唯一例外的是FOR循环里的循环计数变量，该变量被自动声明为整型。</p>
<p>声明语法</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs plsql">variable name [CONSTANT] variable_type [NOT NULL] [&#123;DDEFAULT | :&#x3D; &#125; expression];<br></code></pre></td></tr></table></figure>

<ul>
<li><p>注意：</p>
<ul>
<li><p>SQL数据类型可以作为PL/pgSQL变量的数据类型，如inteser、varchar、char等。例如，声明一个整型变量x，并赋予初始值10：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs plsql">x integer : &#x3D;10;<br></code></pre></td></tr></table></figure>
</li>
<li><p>如果给出DEFAULT子句，该变量进入BEGIN块时将被初始化为默认值，否则被初始化为SQL空值。</p>
</li>
<li><p>CONSTANT选项修饰的变量为常量，在被初始化后不允许被重新赋值。</p>
</li>
<li><p>如果变量声明为NOT NULL，那么该变量不允许被赋予空值NULL，否则运行时会抛出异常信息。因此，所有被声明为NOT NULL的变量，必须在声明时赋予非空的默认值。</p>
</li>
<li><p>声明变量为记录类型，变量声明格式为 <code>variable_name record;</code>。记录型变量类似于数据库表的行，但没有预定义的结构，只能通过SELECT或者FOR命令来获取实际的行结构，因此记录变量在被初始化之前无法访问，否则将引发运行时错误。</p>
<p>需要注意的是，reocrd不是确定结构的数据类型，仅仅声明变量可用来存储数据库表的记录。</p>
</li>
</ul>
</li>
</ul>
<p>实例一：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs plsql">CREATE OR REPLACE FUNCTION displaystudents()<br>	RETURNS void<br>AS $BODY$<br>	DECLARE<br>		src record;<br>	BEGIN<br>		for sc in (select distinct(sid),sname from Student)<br>		loop raise notice &#39;%-,%-&#39;,sc.sid,sc.name;<br>		end loop;<br>	END;<br>$BODY$ LANGUAGE plpgsql<br></code></pre></td></tr></table></figure>

<p>实例二：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs plsql">CREATE OR REPLACE FUNCTION countRecords ()  <br>RETURNS integer AS $count$  <br>declare  <br>    count integer;  <br>BEGIN  <br>   SELECT count(*) into count FROM STUDENT;  <br>   RETURN count;  <br>END;  <br>$count$ LANGUAGE plpgsql;<br></code></pre></td></tr></table></figure>

<p>调用执行存储过程：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs plsql">select totalRecords();<br></code></pre></td></tr></table></figure>

<h4 id="执行存储过程"><a href="#执行存储过程" class="headerlink" title="执行存储过程"></a>执行存储过程</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs plsql">select 存储过程名（参数）；<br>或者： select  * from 存储过程名（参数）；<br>例如： select  countRecords ( );<br>或者：select  * from countRecords ( );<br></code></pre></td></tr></table></figure>

<h4 id="存储过程的参数名"><a href="#存储过程的参数名" class="headerlink" title="存储过程的参数名"></a>存储过程的参数名</h4><p>传递给存储过程的参数都可以用$1、$2的标识符来表示。为了增加可读性，可以为参数声明别名，别名和数字标识符均可以指向该参数值。</p>
<h2 id="触发器"><a href="#触发器" class="headerlink" title="触发器"></a>触发器</h2><p>触发器是存储在数据库中的独立对象，它与存储过程不同，存储过程通过其他程序来启动或直接启动运行，而触发器由一个事件触发启动运行。也就是说，触发器是在某个事件发生时自动地隐式运行，所以启动进行INSERT、UPDATE以及DELETE操作。大多数关系数据库支持触发器，但不同的数据库在触发器的定义和应用方面可能略有不同。</p>
<h1 id="第七章-NoSQL数据库技术（部分了解）"><a href="#第七章-NoSQL数据库技术（部分了解）" class="headerlink" title="第七章 NoSQL数据库技术（部分了解）"></a><strong>第七章 NoSQL数据库技术（部分了解）</strong></h1><p>NoSQL是Not Only SQL的缩写，是对于不同于传统关系数据库的数据库管理系统的统称。它是一种为解决应用需求而提出的海量数据、非结构化数据处理方法的替补方案，大多数的NoSQL产品基于大内存、高性能随机读/写，这些类型的数据存储不需要固定的模式，不需要多余操作就可以横向扩展。</p>
<h2 id="7-1-NoSQL概述"><a href="#7-1-NoSQL概述" class="headerlink" title="7.1 NoSQL概述"></a>7.1 NoSQL概述</h2><ul>
<li>关系数据库的突出优势：<ul>
<li>数据表示的3级模式（外模式、内模式、模式）保证了数据的逻辑独立性与物理独立性，完整的事物处理机制保持了数据的一致性（事物的ACID）</li>
<li>用二维表来表示数据和数据之间的关系，数据更新的开销很小</li>
<li>提供负责连接操作的各种查询处理等</li>
<li>网络和数据库的结合产生了分布式数据库，数据可以分布在网络的不同物理节点上。</li>
<li>数据之间存在着逻辑关系，它们共同完成数据库的全局应用。</li>
</ul>
</li>
</ul>
<p>互联网很多应用要求大批量数据的写入处理，随时更新的数据模式及其索引、字段不固定、对海量数据的简单查询的快速结果反馈，需要全新的数据库技术来为之提供解决方案mNoSQL应运而生。NoSQL使用新的概念数据模型和物理数据模型，新的数据库体系结构，当然也有新的数据库理论支持。</p>
<ul>
<li>数据库管理目标与内容<ul>
<li>数据类型多样化，数字、字符、文本等，还需要视频、音频、图形、图像、动画、HTML/XML、流数据等更复杂的数据类型</li>
<li>数据结构需要结构化、半结构化、非结构化等各种结构</li>
<li>数据存储方式多样化（列式存储、键值存储、图存储、文档存储等）</li>
<li>存储位置–分布透明， 存储量–海量</li>
<li>查询要求多层次：时空、关联、分析、挖掘等</li>
<li>操作需求多样化：各种数据统计分析、分类、聚类、预测、离群点发现等多种操作或自定义操作</li>
</ul>
</li>
</ul>
<h3 id="7-1-1-关系数据库的局限"><a href="#7-1-1-关系数据库的局限" class="headerlink" title="7.1.1 关系数据库的局限"></a>7.1.1 关系数据库的局限</h3><p>关系数据库用二维表的方式来存储数据和数据之间的关系，为OLTP（On Line Transaction Process在线事务处理）提供了数据处理平台</p>
<p>关系数据库以事物为调度单位。</p>
<ul>
<li>面临的挑战：<ul>
<li>数据库高并发读/写需求——大规模事物处理</li>
<li>海量数据的高效存储和处理——各种应用</li>
<li>数据库高扩展性和高可用性需求——云计算</li>
<li>大数据处理方面的需求<ul>
<li>大数据的5V特征：超量、高速、异构、真实、价值</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>海量数据存储的关键技术包括：数据划分、数据一致性和可用性、负载均衡、容错机制、虚拟存储技术、云存储技术。要求数据库必须具有高可扩展性、高并发性、高可用性等特征。</p>
<p>关系数据库的很多主要特性却往往无用武之地：如读一致性、写实时性、读实时性、表的关联查询</p>
<h3 id="7-1-2-NoSQL理论"><a href="#7-1-2-NoSQL理论" class="headerlink" title="7.1.2 NoSQL理论"></a>7.1.2 NoSQL理论</h3><h4 id="1-CAP理论"><a href="#1-CAP理论" class="headerlink" title="1.CAP理论"></a>1.CAP理论</h4><h4 id="2-BASE理论"><a href="#2-BASE理论" class="headerlink" title="2.BASE理论"></a>2.BASE理论</h4><h4 id="3-最终一致性理论"><a href="#3-最终一致性理论" class="headerlink" title="3.最终一致性理论"></a>3.最终一致性理论</h4><h3 id="7-1-3-NoSQL基本概念"><a href="#7-1-3-NoSQL基本概念" class="headerlink" title="7.1.3 NoSQL基本概念"></a>7.1.3 NoSQL基本概念</h3><h4 id="1-NoSQL的含义"><a href="#1-NoSQL的含义" class="headerlink" title="1.NoSQL的含义"></a>1.NoSQL的含义</h4><h4 id="2-NoSQL共同特征"><a href="#2-NoSQL共同特征" class="headerlink" title="2.NoSQL共同特征"></a>2.NoSQL共同特征</h4><h4 id="3-NoSQL采用的技术"><a href="#3-NoSQL采用的技术" class="headerlink" title="3.NoSQL采用的技术"></a>3.NoSQL采用的技术</h4><p>每个记录有唯一的键，不支持外键和跨记录关联。</p>
<p>有些NoSQL没有元数据</p>
<h4 id="4-NoSQL数据库分类"><a href="#4-NoSQL数据库分类" class="headerlink" title="4.NoSQL数据库分类"></a>4.NoSQL数据库分类</h4><h4 id="5-NoSQL整体架构"><a href="#5-NoSQL整体架构" class="headerlink" title="5.NoSQL整体架构"></a>5.NoSQL整体架构</h4><p>接口层-数据逻辑模型层-数据分布层-数据持久层</p>
<h2 id="7-2-列存储数据库"><a href="#7-2-列存储数据库" class="headerlink" title="7.2 列存储数据库"></a>7.2 列存储数据库</h2><h3 id="7-2-1-列存储数据库概念"><a href="#7-2-1-列存储数据库概念" class="headerlink" title="7.2.1 列存储数据库概念"></a>7.2.1 列存储数据库概念</h3><p>列存储索引局限性</p>
<p>列存储索引特点</p>
<h3 id="7-2-2-HBase数据库概念"><a href="#7-2-2-HBase数据库概念" class="headerlink" title="7.2.2 HBase数据库概念"></a>7.2.2 HBase数据库概念</h3><h4 id="HBase表结构"><a href="#HBase表结构" class="headerlink" title="HBase表结构"></a>HBase表结构</h4><p>表</p>
<p>行键</p>
<p>列族</p>
<p>列</p>
<p>单元</p>
<p>时间版本</p>
<p>Hbase数据存储类型</p>
<p>HBase数据的存储类型：模式-&gt;表-&gt;列族-&gt;行键-&gt;时间戳-&gt;单元值</p>
<p>HBase特点</p>
<h3 id="7-2-3HBase数据库的存储架构"><a href="#7-2-3HBase数据库的存储架构" class="headerlink" title="7.2.3HBase数据库的存储架构"></a>7.2.3HBase数据库的存储架构</h3><p>区域是HBase中分布式存储和负载均衡的最小单元。</p>
<p>块是存储管理的最小单元。</p>
<p>表</p>
<p>区域</p>
<p>存储单元：区域由一个或者多个存储单元组成，每个存储单元保存一个列族（每个列族对应一个存储单元）。每个存储单元由一个内存单元和0至多个存储单元组成，每个存储单元保存一个列族。内存单元用于写缓冲，存放临时计算结果。</p>
<p>存储单元文件</p>
<h3 id="7-2-4-HBase数据库的系统架构与组成"><a href="#7-2-4-HBase数据库的系统架构与组成" class="headerlink" title="7.2.4 HBase数据库的系统架构与组成"></a>7.2.4 HBase数据库的系统架构与组成</h3><p>分布式数据库系统</p>
<h4 id="系统架构"><a href="#系统架构" class="headerlink" title="系统架构"></a>系统架构</h4><p>主服务器：”心跳“监听，协调者的主服务器选举机制解决了单点问题。</p>
<p>区域服务器：真实存放HBase的地方；切分过大区域；维护区域并处理I/O请求。</p>
<p>协调者服务器：保证任何时候集群中只有一个主服务器，存储所有区域的寻址入口，实时监控服务器状态，主服务器选举机制。</p>
<p>客户端：使用远程过程调用机制与主服务器和区域服务器进行通信。</p>
<h4 id="系统组成"><a href="#系统组成" class="headerlink" title="系统组成"></a>系统组成</h4><p>日志Hlog</p>
<p>BlockCache</p>
<p>内存缓冲单元</p>
<h3 id="7-2-5-HBase数据库的应用场景"><a href="#7-2-5-HBase数据库的应用场景" class="headerlink" title="7.2.5 HBase数据库的应用场景"></a>7.2.5 HBase数据库的应用场景</h3><p>HBase Shell</p>
<p>Java客户端API</p>
<p>HBase 非Java存取方式</p>
<h2 id="7-3-键值对数据库"><a href="#7-3-键值对数据库" class="headerlink" title="7.3 键值对数据库"></a>7.3 键值对数据库</h2><p>KV数据模型是NoSQL中最基本的数据模型</p>
<p>优点/缺点/使用场景</p>
<p>键值对存储分类：临时性（内存）、永久性（硬盘）、两者兼有（硬盘+内存）</p>
<p>“分片”技术扩展</p>
<h3 id="7-3-1-键值对存储的概念"><a href="#7-3-1-键值对存储的概念" class="headerlink" title="7.3.1 键值对存储的概念"></a>7.3.1 键值对存储的概念</h3><p>基于键值对访问</p>
<ul>
<li>数据模型<ul>
<li>数据结构</li>
<li>数据操作</li>
<li>数据完整性</li>
</ul>
</li>
</ul>
<h3 id="7-3-2-Redis数据库的基本知识"><a href="#7-3-2-Redis数据库的基本知识" class="headerlink" title="7.3.2 Redis数据库的基本知识"></a>7.3.2 Redis数据库的基本知识</h3><h4 id="1-Redis基本概念"><a href="#1-Redis基本概念" class="headerlink" title="1.Redis基本概念"></a>1.Redis基本概念</h4><p>整个数据库统统加载在内存中进行操作，定期通过异步方式把内存数据写（Flush）到硬盘上保存。</p>
<p>支持数据类型：字符串、哈希表、链表、链表、集合、有序集合</p>
<p>受物理内存限制，不能用作海量数据的高性能读写，适合场景局限在较小数据量的高性能操作和运算上。</p>
<h4 id="2-Redis数据库的数据类型"><a href="#2-Redis数据库的数据类型" class="headerlink" title="2.Redis数据库的数据类型"></a>2.Redis数据库的数据类型</h4><p>数据库底层以二进制字节数组的格式存放。</p>
<p>字符串</p>
<p>哈希表：用哈希表内部存储的值为一个哈希映射；哈希表不支持二进制操作命令。</p>
<p>链表：双向链表</p>
<p>集合：通过哈希表实现，增删改查复杂度O(1)，通过计算哈希的方式快速去重。</p>
<p>有序集合：每个元素关联着一个浮点数值，按分值从小到大顺序排列集合元素，成员唯一但浮点数分值可以重复。有序集合内部使用哈希映射和跳跃表来保证数据的存储和有序。</p>
<p>最大值2^32-1</p>
<h3 id="7-3-3-Redis数据库结构"><a href="#7-3-3-Redis数据库结构" class="headerlink" title="7.3.3 Redis数据库结构"></a>7.3.3 Redis数据库结构</h3><h4 id="1-数据库数组"><a href="#1-数据库数组" class="headerlink" title="1.数据库数组"></a>1.数据库数组</h4><p>每个Redis服务器的内部数据结构都是RedisDB[]，Redis默认创建16个数据库。</p>
<h4 id="2-数据库的内部结构"><a href="#2-数据库的内部结构" class="headerlink" title="2.数据库的内部结构"></a>2.数据库的内部结构</h4><p>RedisDB结构中的字典保存了数据库中所有的键值对。</p>
<h4 id="3-字典结构"><a href="#3-字典结构" class="headerlink" title="3.字典结构"></a>3.字典结构</h4><p>Redis底层实现是字典。</p>
<p>字典也是哈希数据底层实现之一。</p>
<p>字典结构包括：字典、哈希表、哈希表的实体、每个键值对的定义</p>
<p>哈希表大小和哈希表中的节点数比例维持在1：1，哈希表的查询性能才能达到最佳查询性能O(1)。</p>
<p>重新哈希问题：渐进式rehash。</p>
<p>哈希实体记录每个键值定义的指针。</p>
<h4 id="4-对象结构"><a href="#4-对象结构" class="headerlink" title="4.对象结构"></a>4.对象结构</h4><p>对象信息：数据类型、编码方式、数据指针、虚拟内存。</p>
<p>编码方式：原始表示、整数、哈希表、链表、压缩表，指针用来指向数据在存储的开始位置等。</p>
<p>字符串实现：简单动态字符串：字符串长度、buf用于存储字符串内容、free表示buf中空闲空间长度</p>
<p>哈希表实现：编码ziplist/linedlist，字符串对象是唯一一种会被其他四种类型对象嵌套的对象。</p>
<p>链表实现：编码ziplist/hashtable。</p>
<p>集合实现：ziplist/intset</p>
<p>有序集合实现：ziplist/skiplist。skiplist编码的有序集合对象使用zset结构作为底层实现，一个zset结构同时包含一个字典和一个跳跃表。</p>
<p>对象其他特性：对象空转时长（设置最大内存选项和最后访问时间选项）、内存回收、对象共享</p>
<h3 id="7-3-4-Redis数据库相关操作"><a href="#7-3-4-Redis数据库相关操作" class="headerlink" title="7.3.4 Redis数据库相关操作"></a>7.3.4 Redis数据库相关操作</h3><h4 id="1-数据库选择"><a href="#1-数据库选择" class="headerlink" title="1.数据库选择"></a>1.数据库选择</h4><p>用内部数组记录多个数据库的使用，数组中的每个db都是一个数据库，SELECT切换数据库。</p>
<h4 id="2-数据库的键空间"><a href="#2-数据库的键空间" class="headerlink" title="2.数据库的键空间"></a>2.数据库的键空间</h4><p>字典保存了数据库中的所有键值对，称为键空间。</p>
<p>取键后，服务器更新最近读取时间，用于计算键的闲置时间。键过期则删除；键被修改添加标记。</p>
<p>服务器每次修改一个键后，都会对键计数器值加1，计数器用来触发服务器持久化操作。</p>
<h4 id="3-设置键的生存时间和过期时间"><a href="#3-设置键的生存时间和过期时间" class="headerlink" title="3.设置键的生存时间和过期时间"></a>3.设置键的生存时间和过期时间</h4><p>经过指定时间之后，服务器会自动删除生存时间为0的键。Redis过期字典记录所有带有过期时间的键，字典的键指向键空间的某个值。</p>
<h4 id="4-过期键删除策略"><a href="#4-过期键删除策略" class="headerlink" title="4.过期键删除策略"></a>4.过期键删除策略</h4><p>定时删除</p>
<p>惰性删除</p>
<p>定时删除</p>
<h4 id="5-复制功能对过期键的处理"><a href="#5-复制功能对过期键的处理" class="headerlink" title="5.复制功能对过期键的处理"></a>5.复制功能对过期键的处理</h4><p>RDB复制和AOF复制</p>
<h4 id="6-Redis内存划分"><a href="#6-Redis内存划分" class="headerlink" title="6.Redis内存划分"></a>6.Redis内存划分</h4><p>数据占用内存、进程运行内存、创建的子进程占用内存、应用系统内存、缓冲内存、客户端缓存、复制积压缓冲、AOF缓存区、内存碎片</p>
<p>安全重启方式减小内存碎片。</p>
<h3 id="7-3-5-Redis数据库的体系结构"><a href="#7-3-5-Redis数据库的体系结构" class="headerlink" title="7.3.5 Redis数据库的体系结构"></a>7.3.5 Redis数据库的体系结构</h3><h4 id="1-Redis集群"><a href="#1-Redis集群" class="headerlink" title="1.Redis集群"></a>1.Redis集群</h4><p>哈希槽概念</p>
<p>集群中每个节点平等，都保存了各自的数据和整个集群的状态。每个节点和其他所有节点连接，这些连接保持活跃，保证了只需要连接集群中任意节点，就可以获取其他节点数据。</p>
<p>集群中必须有3个或3个以上节点。当存活节点数小于总结点数的一半，整个集群无法提供服务。</p>
<p>客户端连接到集群中人一个可用节点即可。</p>
<h4 id="2-Redis主从复制"><a href="#2-Redis主从复制" class="headerlink" title="2.Redis主从复制"></a>2.Redis主从复制</h4><p>主从复制特点：一个主服务器可用有多个从服务器；主服务器可以有从服务器，从服务器也可以有自己的从服务器；支持异步复制和部分复制，主从复制不会阻塞主服务器和从服务器。</p>
<h4 id="3-事物与锁"><a href="#3-事物与锁" class="headerlink" title="3.事物与锁"></a>3.事物与锁</h4><p>MULTI、EXEC、DISCARD、WATCH</p>
<h4 id="4-持久化机制"><a href="#4-持久化机制" class="headerlink" title="4.持久化机制"></a>4.持久化机制</h4><p>将内存中的数据周期性地写入磁盘或者把操作追加到记录文件中。</p>
<p>两种方式地持久化：AOF、RDB</p>
<h4 id="5-发布及订阅消息"><a href="#5-发布及订阅消息" class="headerlink" title="5.发布及订阅消息"></a>5.发布及订阅消息</h4><p>类似于聊天，是一种消息通信模式。发送者将消息发送给频道，频道将消息转发给所有对这个频道感兴趣的订阅者。</p>
<h2 id="7-4-文档数据库"><a href="#7-4-文档数据库" class="headerlink" title="7.4 文档数据库"></a>7.4 文档数据库</h2><p>用于管理文档，文档是处理数据的基本单位</p>
<p>文档相当于关系数据库中的一条记录，能对包含的数据类型内容进行”自我描述“，XML文档、HTML文档和JSON文档就属于这一类。</p>
<p>文档数据库提供嵌入式文档，可用于需要存储不同的属性及大量数据的应用系统。</p>
<h3 id="7-4-1-文档存储概念"><a href="#7-4-1-文档存储概念" class="headerlink" title="7.4.1 文档存储概念"></a>7.4.1 文档存储概念</h3><h3 id="7-4-2-MongoDB数据库的基本概念"><a href="#7-4-2-MongoDB数据库的基本概念" class="headerlink" title="7.4.2 MongoDB数据库的基本概念"></a>7.4.2 MongoDB数据库的基本概念</h3><h3 id="7-4-3-MongoDB的管理"><a href="#7-4-3-MongoDB的管理" class="headerlink" title="7.4.3 MongoDB的管理"></a>7.4.3 MongoDB的管理</h3><h3 id="7-4-4-MongoDB数据库的集群架构"><a href="#7-4-4-MongoDB数据库的集群架构" class="headerlink" title="7.4.4 MongoDB数据库的集群架构"></a>7.4.4 MongoDB数据库的集群架构</h3><h3 id="7-4-5-MongDB数据库的应用场景"><a href="#7-4-5-MongDB数据库的应用场景" class="headerlink" title="7.4.5 MongDB数据库的应用场景"></a>7.4.5 MongDB数据库的应用场景</h3><h2 id="7-5-图形数据库"><a href="#7-5-图形数据库" class="headerlink" title="7.5 图形数据库"></a>7.5 图形数据库</h2>
            </div>
            <hr>
            <div>
              <div class="post-metas mb-3">
                
                
                  <div class="post-meta">
                    <i class="iconfont icon-tags"></i>
                    
                      <a class="hover-with-bg" href="/tags/%E6%95%B0%E6%8D%AE%E5%BA%93/">数据库</a>
                    
                  </div>
                
              </div>
              
                <p class="note note-warning">
                  
                    本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-sa/4.0/deed.zh" rel="nofollow noopener">CC BY-SA 4.0 协议</a> ，转载请注明出处！
                  
                </p>
              
              
                <div class="post-prevnext">
                  <article class="post-prev col-6">
                    
                    
                      <a href="/2021/05/21/%E5%89%8D%E7%AB%AF%E5%AD%A6%E4%B9%A014/">
                        <i class="iconfont icon-arrowleft"></i>
                        <span class="hidden-mobile">项目实战—纽曼官网实现</span>
                        <span class="visible-mobile">上一篇</span>
                      </a>
                    
                  </article>
                  <article class="post-next col-6">
                    
                    
                      <a href="/2021/05/10/%E5%89%8D%E7%AB%AF%E5%AD%A6%E4%B9%A013/">
                        <span class="hidden-mobile">PhotoShop基础</span>
                        <span class="visible-mobile">下一篇</span>
                        <i class="iconfont icon-arrowright"></i>
                      </a>
                    
                  </article>
                </div>
              
            </div>

            
          </article>
        </div>
      </div>
    </div>
    
      <div class="d-none d-lg-block col-lg-2 toc-container" id="toc-ctn">
        <div id="toc">
  <p class="toc-header"><i class="iconfont icon-list"></i>&nbsp;目录</p>
  <div class="toc-body" id="toc-body"></div>
</div>

      </div>
    
  </div>
</div>

<!-- Custom -->

  <div class="col-lg-7 mx-auto nopadding-x-md">
    <div class="container custom post-custom mx-auto">
      <img src="https://octodex.github.com/images/jetpacktocat.png" srcset="/img/loading.gif" class="rounded mx-auto d-block mt-5" style="width:150px; height:150px;">
    </div>
  </div>


    

    
      <a id="scroll-top-button" href="#" role="button">
        <i class="iconfont icon-arrowup" aria-hidden="true"></i>
      </a>
    

    
      <div class="modal fade" id="modalSearch" tabindex="-1" role="dialog" aria-labelledby="ModalLabel"
     aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header text-center">
        <h4 class="modal-title w-100 font-weight-bold">搜索</h4>
        <button type="button" id="local-search-close" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body mx-3">
        <div class="md-form mb-5">
          <input type="text" id="local-search-input" class="form-control validate">
          <label data-error="x" data-success="v"
                 for="local-search-input">关键词</label>
        </div>
        <div class="list-group" id="local-search-result"></div>
      </div>
    </div>
  </div>
</div>
    

    
  </main>

  <footer class="text-center mt-5 py-3">
  <div class="footer-content">
     <a href="https://hexo.io" target="_blank" rel="nofollow noopener"><span>Hexo</span></a> <i class="iconfont icon-love"></i> <a href="https://github.com/fluid-dev/hexo-theme-fluid" target="_blank" rel="nofollow noopener"><span>Fluid</span></a> 
  </div>
  

  
  <!-- 备案信息 -->
  <div class="beian">
    <span>
      <a href="http://beian.miit.gov.cn/" target="_blank" rel="nofollow noopener">
        京ICP证123456号
      </a>
    </span>
    
      
        <span>
          <a
            href="http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=12345678"
            rel="nofollow noopener"
            class="beian-police"
            target="_blank"
          >
            
              <span style="visibility: hidden; width: 0">|</span>
              <img src="/img/police_beian.png" srcset="/img/loading.gif" alt="police-icon"/>
            
            <span>京公网安备12345678号</span>
          </a>
        </span>
      
    
  </div>


  
</footer>

<!-- SCRIPTS -->

  <script  src="https://cdn.jsdelivr.net/npm/nprogress@0.2.0/nprogress.min.js" ></script>
  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/nprogress@0.2.0/nprogress.min.css" />

  <script>
    NProgress.configure({"showSpinner":false,"trickleSpeed":100})
    NProgress.start()
    window.addEventListener('load', function() {
      NProgress.done();
    })
  </script>


<script  src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js" ></script>
<script  src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.min.js" ></script>
<script  src="/js/debouncer.js" ></script>
<script  src="/js/events.js" ></script>
<script  src="/js/plugins.js" ></script>

<!-- Plugins -->


  
    <script  src="/js/lazyload.js" ></script>
  



  



  <script  src="https://cdn.jsdelivr.net/npm/tocbot@4.12.0/dist/tocbot.min.js" ></script>



  <script  src="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.js" ></script>



  <script  src="https://cdn.jsdelivr.net/npm/anchor-js@4.3.0/anchor.min.js" ></script>



  <script defer src="https://cdn.jsdelivr.net/npm/clipboard@2.0.6/dist/clipboard.min.js" ></script>



  <script defer src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js" ></script>




  <script  src="https://cdn.jsdelivr.net/npm/typed.js@2.0.11/lib/typed.min.js" ></script>
  <script>
    (function (window, document) {
      var typing = Fluid.plugins.typing;
      var title = document.getElementById('subtitle').title;
      
      typing(title)
      
    })(window, document);
  </script>



  <script  src="/js/local-search.js" ></script>
  <script>
    (function () {
      var path = "/local-search.xml";
      $('#local-search-input').on('click', function() {
        searchFunc(path, 'local-search-input', 'local-search-result');
      });
      $('#modalSearch').on('shown.bs.modal', function() {
        $('#local-search-input').focus();
      });
    })()
  </script>















<!-- 主题的启动项 保持在最底部 -->
<script  src="/js/boot.js" ></script>



<script src="/live2dw/lib/L2Dwidget.min.js?094cbace49a39548bed64abff5988b05"></script><script>L2Dwidget.init({"pluginRootPath":"live2dw/","pluginJsPath":"lib/","pluginModelPath":"assets/","tagMode":false,"debug":false,"model":{"scale":1,"hHeadPos":0.5,"vHeadPos":0.618,"jsonPath":"/live2dw/assets/shizuku.model.json"},"display":{"superSample":2,"width":150,"height":300,"position":"right","hOffset":0,"vOffset":-20},"mobile":{"show":true,"scale":0.5},"react":{"opacityDefault":0.7,"opacityOnHover":0.8},"log":false});</script></body>
</html>
